{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","index.js","dagre-d3.core.js","lib/arrows.js","lib/create-clusters.js","lib/create-edge-labels.js","lib/create-edge-paths.js","lib/create-nodes.js","lib/d3.js","lib/dagre.js","lib/graphlib.js","lib/intersect/index.js","lib/intersect/intersect-circle.js","lib/intersect/intersect-ellipse.js","lib/intersect/intersect-line.js","lib/intersect/intersect-node.js","lib/intersect/intersect-polygon.js","lib/intersect/intersect-rect.js","lib/label/add-html-label.js","lib/label/add-label.js","lib/label/add-svg-label.js","lib/label/add-text-label.js","lib/lodash.js","lib/position-clusters.js","lib/position-edge-labels.js","lib/position-nodes.js","lib/render.js","lib/shapes.js","lib/util.js","lib/version.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","dagreD3","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length",1,"graphlib","dagre","intersect","render","util","version","./lib/dagre","./lib/graphlib","./lib/intersect","./lib/render","./lib/util","./lib/version",2,"normal","parent","id","edge","type","marker","append","attr","path","style","applyStyle","vee","undirected","default","./util",3,"createClusters","selection","clusters","nodes","filter","v","isSubgraph","svgClusters","selectAll","data","remove","enter","node","applyTransition","each","thisGroup","d3","select","labelGroup","addLabel","clusterLabelPos","c","domCluster","exit","./label/add-label",4,"createEdgeLabels","svgEdgeLabels","edges","edgeToId","classed","label","bbox","getBBox","labelId","_","has","width","height","./d3","./lodash",5,"createEdgePaths","arrows","svgPaths","domEdge","elem","applyClass","arrowheadId","uniqueId","makeFragmentRef","location","href","calcPoints","arrowhead","url","fragmentId","baseUrl","split","tail","head","w","points","slice","unshift","intersectNode","push","createLine","line","svg","x","d","y","interpolate","lineInterpolate","tension","Number","lineTension","getCoords","matrix","ownerSVGElement","getScreenCTM","inverse","multiply","translate","svgPathsEnter","sourceElem","range","map","svgPathExit","source","getTotalLength","./intersect/intersect-node",6,"createNodes","shapes","simpleNodes","svgNodes","labelDom","shape","pick","paddingLeft","paddingRight","paddingTop","paddingBottom","shapeSvg","shapeBBox",7,8,"undefined",9,10,"circle","ellipse","polygon","rect","./intersect-circle","./intersect-ellipse","./intersect-node","./intersect-polygon","./intersect-rect",11,"intersectCircle","rx","point","intersectEllipse",12,"ry","cx","cy","px","py","det","Math","sqrt","dx","abs","dy",13,"intersectLine","p1","p2","q1","q2","a1","a2","b1","b2","c1","c2","r1","r2","r3","r4","denom","offset","num","sameSign",14,15,"intersectPolygon","polyPoints","x1","y1","intersections","minX","POSITIVE_INFINITY","minY","forEach","entry","min","left","top","sort","p","q","pdx","pdy","distp","qdx","qdy","distq","console","log","./intersect-line",16,"intersectRect","sx","sy","h",17,"addHtmlLabel","root","fo","div","insert","html","labelStyle","client","getBoundingClientRect","../util",18,"labelSvg","labelType","addSVGLabel","addTextLabel","labelBBox","./add-html-label","./add-svg-label","./add-text-label",19,"domNode","appendChild",20,"lines","processEscapeSequences","text","ch","newText","escaped",21,"lodash",22,"positionClusters","created",23,"positionEdgeLabels",24,"positionNodes",25,"fn","preProcessGraph","outputGroup","createOrSelectGroup","clustersGroup","edgePathsGroup","edgeLabels","layout","postProcessGraph","value","arguments","children","defaults","paddingX","paddingY","padding","NODE_DEFAULT_ATTRS","k","_prevWidth","_prevHeight","EDGE_DEFAULT_ATTRS","name","empty","./arrows","./create-clusters","./create-edge-labels","./create-edge-paths","./create-nodes","./dagre","./position-clusters","./position-edge-labels","./position-nodes","./shapes",26,"max","diamond","SQRT2","join","./intersect/intersect-circle","./intersect/intersect-ellipse","./intersect/intersect-polygon","./intersect/intersect-rect",27,"escapeId","str","String","replace","ID_DELIM","dom","styleFn","classFn","otherClasses","graph","isPlainObject","transition","isFunction",28],"mappings":"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","file":"dagre-d3.core.min.js","sourcesContent":["(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})","/**\n * @license\n * Copyright (c) 2012-2013 Chris Pettitt\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\nmodule.exports =  {\n  graphlib: require(\"./lib/graphlib\"),\n  dagre: require(\"./lib/dagre\"),\n  intersect: require(\"./lib/intersect\"),\n  render: require(\"./lib/render\"),\n  util: require(\"./lib/util\"),\n  version: require(\"./lib/version\")\n};\n","(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){\n/**\n * @license\n * Copyright (c) 2012-2013 Chris Pettitt\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\nmodule.exports =  {\n  graphlib: require(\"./lib/graphlib\"),\n  dagre: require(\"./lib/dagre\"),\n  intersect: require(\"./lib/intersect\"),\n  render: require(\"./lib/render\"),\n  util: require(\"./lib/util\"),\n  version: require(\"./lib/version\")\n};\n\n},{\"./lib/dagre\":8,\"./lib/graphlib\":9,\"./lib/intersect\":10,\"./lib/render\":25,\"./lib/util\":27,\"./lib/version\":28}],2:[function(require,module,exports){\nvar util = require(\"./util\");\n\nmodule.exports = {\n  \"default\": normal,\n  \"normal\": normal,\n  \"vee\": vee,\n  \"undirected\": undirected\n};\n\nfunction normal(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 0 L 10 5 L 0 10 z\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n\nfunction vee(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 0 L 10 5 L 0 10 L 4 5 z\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n\nfunction undirected(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 5 L 10 5\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n\n},{\"./util\":27}],3:[function(require,module,exports){\nvar util = require(\"./util\"),\n    addLabel = require(\"./label/add-label\");\n\nmodule.exports = createClusters;\n\nfunction createClusters(selection, g) {\n  var clusters = g.nodes().filter(function(v) { return util.isSubgraph(g, v); }),\n      svgClusters = selection.selectAll(\"g.cluster\")\n        .data(clusters, function(v) { return v; });\n\n  svgClusters.selectAll(\"*\").remove();\n  svgClusters.enter()\n    .append(\"g\")\n      .attr(\"class\", \"cluster\")\n      .attr(\"id\",function(v){\n          var node = g.node(v);\n          return node.id;\n      })\n      .style(\"opacity\", 0);\n\n  util.applyTransition(svgClusters, g)\n    .style(\"opacity\", 1);\n\n  svgClusters.each(function(v) {\n    var node = g.node(v),\n        thisGroup = d3.select(this);\n    d3.select(this).append(\"rect\");\n    var labelGroup = thisGroup.append(\"g\").attr(\"class\", \"label\");\n    addLabel(labelGroup, node, node.clusterLabelPos);\n  });\n\n  svgClusters.selectAll(\"rect\").each(function(c) {\n    var node = g.node(c);\n    var domCluster = d3.select(this);\n    util.applyStyle(domCluster, node.style);\n  });\n\n  util.applyTransition(svgClusters.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgClusters;\n}\n\n},{\"./label/add-label\":18,\"./util\":27}],4:[function(require,module,exports){\n\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    addLabel = require(\"./label/add-label\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = createEdgeLabels;\n\nfunction createEdgeLabels(selection, g) {\n  var svgEdgeLabels = selection.selectAll(\"g.edgeLabel\")\n    .data(g.edges(), function(e) { return util.edgeToId(e); })\n    .classed(\"update\", true);\n\n  svgEdgeLabels.selectAll(\"*\").remove();\n  svgEdgeLabels.enter()\n    .append(\"g\")\n      .classed(\"edgeLabel\", true)\n      .style(\"opacity\", 0);\n  svgEdgeLabels.each(function(e) {\n    var edge = g.edge(e),\n        label = addLabel(d3.select(this), g.edge(e), 0, 0).classed(\"label\", true),\n        bbox = label.node().getBBox();\n\n    if (edge.labelId) { label.attr(\"id\", edge.labelId); }\n    if (!_.has(edge, \"width\")) { edge.width = bbox.width; }\n    if (!_.has(edge, \"height\")) { edge.height = bbox.height; }\n  });\n\n  util.applyTransition(svgEdgeLabels.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgEdgeLabels;\n}\n\n},{\"./d3\":7,\"./label/add-label\":18,\"./lodash\":21,\"./util\":27}],5:[function(require,module,exports){\n\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    intersectNode = require(\"./intersect/intersect-node\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\nmodule.exports = createEdgePaths;\n\nfunction createEdgePaths(selection, g, arrows) {\n  var svgPaths = selection.selectAll(\"g.edgePath\")\n    .data(g.edges(), function(e) { return util.edgeToId(e); })\n    .classed(\"update\", true);\n\n  enter(svgPaths, g);\n  exit(svgPaths, g);\n\n  util.applyTransition(svgPaths, g)\n    .style(\"opacity\", 1);\n\n  // Save DOM element in the path group, and set ID and class\n  svgPaths.each(function(e) {\n    var domEdge = d3.select(this);\n    var edge = g.edge(e);\n    edge.elem = this;\n\n    if (edge.id) {\n      domEdge.attr(\"id\", edge.id);\n    }\n\n    util.applyClass(domEdge, edge[\"class\"],\n      (domEdge.classed(\"update\") ? \"update \" : \"\") + \"edgePath\");\n  });\n\n  svgPaths.selectAll(\"path.path\")\n    .each(function(e) {\n      var edge = g.edge(e);\n      edge.arrowheadId = _.uniqueId(\"arrowhead\");\n\n      var domEdge = d3.select(this)\n        .attr(\"marker-end\", function() {\n            return \"url(\" + makeFragmentRef(location.href, edge.arrowheadId) + \")\";\n        })\n        .style(\"fill\", \"none\");\n\n      util.applyTransition(domEdge, g)\n        .attr(\"d\", function(e) { return calcPoints(g, e); });\n\n      util.applyStyle(domEdge, edge.style);\n    });\n\n  svgPaths.selectAll(\"defs *\").remove();\n  svgPaths.selectAll(\"defs\")\n    .each(function(e) {\n      var edge = g.edge(e),\n          arrowhead = arrows[edge.arrowhead];\n      arrowhead(d3.select(this), edge.arrowheadId, edge, \"arrowhead\");\n    });\n\n  return svgPaths;\n}\n\nfunction makeFragmentRef(url, fragmentId) {\n  var baseUrl = url.split(\"#\")[0];\n  return baseUrl + \"#\" + fragmentId;\n}\n\nfunction calcPoints(g, e) {\n  var edge = g.edge(e),\n      tail = g.node(e.v),\n      head = g.node(e.w),\n      points = edge.points.slice(1, edge.points.length - 1);\n  points.unshift(intersectNode(tail, points[0]));\n  points.push(intersectNode(head, points[points.length - 1]));\n\n  return createLine(edge, points);\n}\n\nfunction createLine(edge, points) {\n  var line = d3.svg.line()\n    .x(function(d) { return d.x; })\n    .y(function(d) { return d.y; });\n\n  if (_.has(edge, \"lineInterpolate\")) {\n    line.interpolate(edge.lineInterpolate);\n  }\n\n  if (_.has(edge, \"lineTension\")) {\n    line.tension(Number(edge.lineTension));\n  }\n\n  return line(points);\n}\n\nfunction getCoords(elem) {\n  var bbox = elem.getBBox(),\n      matrix = elem.ownerSVGElement.getScreenCTM()\n        .inverse()\n        .multiply(elem.getScreenCTM())\n        .translate(bbox.width / 2, bbox.height / 2);\n  return { x: matrix.e, y: matrix.f };\n}\n\nfunction enter(svgPaths, g) {\n  var svgPathsEnter = svgPaths.enter()\n    .append(\"g\")\n      .attr(\"class\", \"edgePath\")\n      .style(\"opacity\", 0);\n  svgPathsEnter.append(\"path\")\n    .attr(\"class\", \"path\")\n    .attr(\"d\", function(e) {\n      var edge = g.edge(e),\n          sourceElem = g.node(e.v).elem,\n          points = _.range(edge.points.length).map(function() { return getCoords(sourceElem); });\n      return createLine(edge, points);\n    });\n  svgPathsEnter.append(\"defs\");\n}\n\nfunction exit(svgPaths, g) {\n  var svgPathExit = svgPaths.exit();\n  util.applyTransition(svgPathExit, g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  util.applyTransition(svgPathExit.select(\"path.path\"), g)\n    .attr(\"d\", function(e) {\n      var source = g.node(e.v);\n\n      if (source) {\n        var points = _.range(this.getTotalLength()).map(function() { return source; });\n        return createLine({}, points);\n      } else {\n        return d3.select(this).attr(\"d\");\n      }\n    });\n}\n\n},{\"./d3\":7,\"./intersect/intersect-node\":14,\"./lodash\":21,\"./util\":27}],6:[function(require,module,exports){\n\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    addLabel = require(\"./label/add-label\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = createNodes;\n\nfunction createNodes(selection, g, shapes) {\n  var simpleNodes = g.nodes().filter(function(v) { return !util.isSubgraph(g, v); });\n  var svgNodes = selection.selectAll(\"g.node\")\n    .data(simpleNodes, function(v) { return v; })\n    .classed(\"update\", true);\n\n  svgNodes.selectAll(\"*\").remove();\n  svgNodes.enter()\n    .append(\"g\")\n      .attr(\"class\", \"node\")\n      .style(\"opacity\", 0);\n  svgNodes.each(function(v) {\n    var node = g.node(v),\n        thisGroup = d3.select(this),\n        labelGroup = thisGroup.append(\"g\").attr(\"class\", \"label\"),\n        labelDom = addLabel(labelGroup, node),\n        shape = shapes[node.shape],\n        bbox = _.pick(labelDom.node().getBBox(), \"width\", \"height\");\n\n    node.elem = this;\n\n    if (node.id) { thisGroup.attr(\"id\", node.id); }\n    if (node.labelId) { labelGroup.attr(\"id\", node.labelId); }\n    util.applyClass(thisGroup, node[\"class\"],\n      (thisGroup.classed(\"update\") ? \"update \" : \"\") + \"node\");\n\n    if (_.has(node, \"width\")) { bbox.width = node.width; }\n    if (_.has(node, \"height\")) { bbox.height = node.height; }\n\n    bbox.width += node.paddingLeft + node.paddingRight;\n    bbox.height += node.paddingTop + node.paddingBottom;\n    labelGroup.attr(\"transform\", \"translate(\" +\n      ((node.paddingLeft - node.paddingRight) / 2) + \",\" +\n      ((node.paddingTop - node.paddingBottom) / 2) + \")\");\n\n    var shapeSvg = shape(d3.select(this), bbox, node);\n    util.applyStyle(shapeSvg, node.style);\n\n    var shapeBBox = shapeSvg.node().getBBox();\n    node.width = shapeBBox.width;\n    node.height = shapeBBox.height;\n  });\n\n  util.applyTransition(svgNodes.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgNodes;\n}\n\n},{\"./d3\":7,\"./label/add-label\":18,\"./lodash\":21,\"./util\":27}],7:[function(require,module,exports){\n// Stub to get D3 either via NPM or from the global object\nmodule.exports = window.d3;\n\n},{}],8:[function(require,module,exports){\n/* global window */\n\nvar dagre;\n\nif (require) {\n  try {\n    dagre = require(\"dagre\");\n  } catch (e) {}\n}\n\nif (!dagre) {\n  dagre = window.dagre;\n}\n\nmodule.exports = dagre;\n\n},{\"dagre\":undefined}],9:[function(require,module,exports){\n/* global window */\n\nvar graphlib;\n\nif (require) {\n  try {\n    graphlib = require(\"graphlib\");\n  } catch (e) {}\n}\n\nif (!graphlib) {\n  graphlib = window.graphlib;\n}\n\nmodule.exports = graphlib;\n\n},{\"graphlib\":undefined}],10:[function(require,module,exports){\nmodule.exports = {\n  node: require(\"./intersect-node\"),\n  circle: require(\"./intersect-circle\"),\n  ellipse: require(\"./intersect-ellipse\"),\n  polygon: require(\"./intersect-polygon\"),\n  rect: require(\"./intersect-rect\")\n};\n\n},{\"./intersect-circle\":11,\"./intersect-ellipse\":12,\"./intersect-node\":14,\"./intersect-polygon\":15,\"./intersect-rect\":16}],11:[function(require,module,exports){\nvar intersectEllipse = require(\"./intersect-ellipse\");\n\nmodule.exports = intersectCircle;\n\nfunction intersectCircle(node, rx, point) {\n  return intersectEllipse(node, rx, rx, point);\n}\n\n},{\"./intersect-ellipse\":12}],12:[function(require,module,exports){\nmodule.exports = intersectEllipse;\n\nfunction intersectEllipse(node, rx, ry, point) {\n  // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html\n\n  var cx = node.x;\n  var cy = node.y;\n\n  var px = cx - point.x;\n  var py = cy - point.y;\n\n  var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);\n\n  var dx = Math.abs(rx * ry * px / det);\n  if (point.x < cx) {\n    dx = -dx;\n  }\n  var dy = Math.abs(rx * ry * py / det);\n  if (point.y < cy) {\n    dy = -dy;\n  }\n\n  return {x: cx + dx, y: cy + dy};\n}\n\n\n},{}],13:[function(require,module,exports){\nmodule.exports = intersectLine;\n\n/*\n * Returns the point at which two lines, p and q, intersect or returns\n * undefined if they do not intersect.\n */\nfunction intersectLine(p1, p2, q1, q2) {\n  // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994,\n  // p7 and p473.\n\n  var a1, a2, b1, b2, c1, c2;\n  var r1, r2 , r3, r4;\n  var denom, offset, num;\n  var x, y;\n\n  // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x +\n  // b1 y + c1 = 0.\n  a1 = p2.y - p1.y;\n  b1 = p1.x - p2.x;\n  c1 = (p2.x * p1.y) - (p1.x * p2.y);\n\n  // Compute r3 and r4.\n  r3 = ((a1 * q1.x) + (b1 * q1.y) + c1);\n  r4 = ((a1 * q2.x) + (b1 * q2.y) + c1);\n\n  // Check signs of r3 and r4. If both point 3 and point 4 lie on\n  // same side of line 1, the line segments do not intersect.\n  if ((r3 !== 0) && (r4 !== 0) && sameSign(r3, r4)) {\n    return /*DONT_INTERSECT*/;\n  }\n\n  // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0\n  a2 = q2.y - q1.y;\n  b2 = q1.x - q2.x;\n  c2 = (q2.x * q1.y) - (q1.x * q2.y);\n\n  // Compute r1 and r2\n  r1 = (a2 * p1.x) + (b2 * p1.y) + c2;\n  r2 = (a2 * p2.x) + (b2 * p2.y) + c2;\n\n  // Check signs of r1 and r2. If both point 1 and point 2 lie\n  // on same side of second line segment, the line segments do\n  // not intersect.\n  if ((r1 !== 0) && (r2 !== 0) && (sameSign(r1, r2))) {\n    return /*DONT_INTERSECT*/;\n  }\n\n  // Line segments intersect: compute intersection point.\n  denom = (a1 * b2) - (a2 * b1);\n  if (denom === 0) {\n    return /*COLLINEAR*/;\n  }\n\n  offset = Math.abs(denom / 2);\n\n  // The denom/2 is to get rounding instead of truncating. It\n  // is added or subtracted to the numerator, depending upon the\n  // sign of the numerator.\n  num = (b1 * c2) - (b2 * c1);\n  x = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);\n\n  num = (a2 * c1) - (a1 * c2);\n  y = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);\n\n  return { x: x, y: y };\n}\n\nfunction sameSign(r1, r2) {\n  return r1 * r2 > 0;\n}\n\n},{}],14:[function(require,module,exports){\nmodule.exports = intersectNode;\n\nfunction intersectNode(node, point) {\n  return node.intersect(point);\n}\n\n},{}],15:[function(require,module,exports){\nvar intersectLine = require(\"./intersect-line\");\n\nmodule.exports = intersectPolygon;\n\n/*\n * Returns the point ({x, y}) at which the point argument intersects with the\n * node argument assuming that it has the shape specified by polygon.\n */\nfunction intersectPolygon(node, polyPoints, point) {\n  var x1 = node.x;\n  var y1 = node.y;\n\n  var intersections = [];\n\n  var minX = Number.POSITIVE_INFINITY,\n      minY = Number.POSITIVE_INFINITY;\n  polyPoints.forEach(function(entry) {\n    minX = Math.min(minX, entry.x);\n    minY = Math.min(minY, entry.y);\n  });\n\n  var left = x1 - node.width / 2 - minX;\n  var top =  y1 - node.height / 2 - minY;\n\n  for (var i = 0; i < polyPoints.length; i++) {\n    var p1 = polyPoints[i];\n    var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];\n    var intersect = intersectLine(node, point,\n      {x: left + p1.x, y: top + p1.y}, {x: left + p2.x, y: top + p2.y});\n    if (intersect) {\n      intersections.push(intersect);\n    }\n  }\n\n  if (!intersections.length) {\n    console.log(\"NO INTERSECTION FOUND, RETURN NODE CENTER\", node);\n    return node;\n  }\n\n  if (intersections.length > 1) {\n    // More intersections, find the one nearest to edge end point\n    intersections.sort(function(p, q) {\n      var pdx = p.x - point.x,\n          pdy = p.y - point.y,\n          distp = Math.sqrt(pdx * pdx + pdy * pdy),\n\n          qdx = q.x - point.x,\n          qdy = q.y - point.y,\n          distq = Math.sqrt(qdx * qdx + qdy * qdy);\n\n      return (distp < distq) ? -1 : (distp === distq ? 0 : 1);\n    });\n  }\n  return intersections[0];\n}\n\n},{\"./intersect-line\":13}],16:[function(require,module,exports){\nmodule.exports = intersectRect;\n\nfunction intersectRect(node, point) {\n  var x = node.x;\n  var y = node.y;\n\n  // Rectangle intersection algorithm from:\n  // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes\n  var dx = point.x - x;\n  var dy = point.y - y;\n  var w = node.width / 2;\n  var h = node.height / 2;\n\n  var sx, sy;\n  if (Math.abs(dy) * w > Math.abs(dx) * h) {\n    // Intersection is top or bottom of rect.\n    if (dy < 0) {\n      h = -h;\n    }\n    sx = dy === 0 ? 0 : h * dx / dy;\n    sy = h;\n  } else {\n    // Intersection is left or right of rect.\n    if (dx < 0) {\n      w = -w;\n    }\n    sx = w;\n    sy = dx === 0 ? 0 : w * dy / dx;\n  }\n\n  return {x: x + sx, y: y + sy};\n}\n\n},{}],17:[function(require,module,exports){\nvar util = require(\"../util\");\n\nmodule.exports = addHtmlLabel;\n\nfunction addHtmlLabel(root, node) {\n  var fo = root\n    .append(\"foreignObject\")\n      .attr(\"width\", \"100000\");\n\n  var div = fo\n    .append(\"xhtml:div\");\n  div.attr(\"xmlns\", \"http://www.w3.org/1999/xhtml\");\n\n  var label = node.label;\n  switch(typeof label) {\n    case \"function\":\n      div.insert(label);\n      break;\n    case \"object\":\n      // Currently we assume this is a DOM object.\n      div.insert(function() { return label; });\n      break;\n    default: div.html(label);\n  }\n\n  util.applyStyle(div, node.labelStyle);\n  div.style(\"display\", \"inline-block\");\n  // Fix for firefox\n  div.style(\"white-space\", \"nowrap\");\n\n  var client = div[0][0].getBoundingClientRect();\n  fo\n    .attr(\"width\", client.width)\n    .attr(\"height\", client.height); \n\n  return fo;\n}\n\n},{\"../util\":27}],18:[function(require,module,exports){\nvar addTextLabel = require(\"./add-text-label\"),\n    addHtmlLabel = require(\"./add-html-label\"),\n    addSVGLabel  = require(\"./add-svg-label\");\n\nmodule.exports = addLabel;\n\nfunction addLabel(root, node, location) {\n  var label = node.label;\n  var labelSvg = root.append(\"g\");\n\n  // Allow the label to be a string, a function that returns a DOM element, or\n  // a DOM element itself.\n  if (node.labelType === \"svg\") {\n    addSVGLabel(labelSvg, node);\n  } else if (typeof label !== \"string\" || node.labelType === \"html\") {\n    addHtmlLabel(labelSvg, node);\n  } else {\n    addTextLabel(labelSvg, node);\n  }\n\n  var labelBBox = labelSvg.node().getBBox();\n  var y;\n  switch(location) {\n    case \"top\":\n      y = (-node.height / 2);\n      break;\n    case \"bottom\":\n      y = (node.height / 2) - labelBBox.height;\n      break;\n    default:\n      y = (-labelBBox.height / 2);\n  }\n  labelSvg.attr(\"transform\",\n                \"translate(\" + (-labelBBox.width / 2) + \",\" + y + \")\");\n\n  return labelSvg;\n}\n\n},{\"./add-html-label\":17,\"./add-svg-label\":19,\"./add-text-label\":20}],19:[function(require,module,exports){\nvar util = require(\"../util\");\n\nmodule.exports = addSVGLabel;\n\nfunction addSVGLabel(root, node) {\n  var domNode = root;\n\n  domNode.node().appendChild(node.label);\n\n  util.applyStyle(domNode, node.labelStyle);\n\n  return domNode;\n}\n\n},{\"../util\":27}],20:[function(require,module,exports){\nvar util = require(\"../util\");\n\nmodule.exports = addTextLabel;\n\n/*\n * Attaches a text label to the specified root. Handles escape sequences.\n */\nfunction addTextLabel(root, node) {\n  var domNode = root.append(\"text\");\n\n  var lines = processEscapeSequences(node.label).split(\"\\n\");\n  for (var i = 0; i < lines.length; i++) {\n    domNode\n      .append(\"tspan\")\n        .attr(\"xml:space\", \"preserve\")\n        .attr(\"dy\", \"1em\")\n        .attr(\"x\", \"1\")\n        .text(lines[i]);\n  }\n\n  util.applyStyle(domNode, node.labelStyle);\n\n  return domNode;\n}\n\nfunction processEscapeSequences(text) {\n  var newText = \"\",\n      escaped = false,\n      ch;\n  for (var i = 0; i < text.length; ++i) {\n    ch = text[i];\n    if (escaped) {\n      switch(ch) {\n        case \"n\": newText += \"\\n\"; break;\n        default: newText += ch;\n      }\n      escaped = false;\n    } else if (ch === \"\\\\\") {\n      escaped = true;\n    } else {\n      newText += ch;\n    }\n  }\n  return newText;\n}\n\n},{\"../util\":27}],21:[function(require,module,exports){\n/* global window */\n\nvar lodash;\n\nif (require) {\n  try {\n    lodash = require(\"lodash\");\n  } catch (e) {}\n}\n\nif (!lodash) {\n  lodash = window._;\n}\n\nmodule.exports = lodash;\n\n},{\"lodash\":undefined}],22:[function(require,module,exports){\n\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = positionClusters;\n\nfunction positionClusters(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(v) {\n    var node = g.node(v);\n    return \"translate(\" + node.x + \",\" + node.y + \")\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n      .style(\"opacity\", 1)\n      .attr(\"transform\", translate);\n\n  util.applyTransition(created.selectAll(\"rect\"), g)\n      .attr(\"width\", function(v) { return g.node(v).width; })\n      .attr(\"height\", function(v) { return g.node(v).height; })\n      .attr(\"x\", function(v) {\n        var node = g.node(v);\n        return -node.width / 2;\n      })\n      .attr(\"y\", function(v) {\n        var node = g.node(v);\n        return -node.height / 2;\n      });\n\n}\n\n},{\"./d3\":7,\"./util\":27}],23:[function(require,module,exports){\n\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\"),\n    _ = require(\"./lodash\");\n\nmodule.exports = positionEdgeLabels;\n\nfunction positionEdgeLabels(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(e) {\n    var edge = g.edge(e);\n    return _.has(edge, \"x\") ? \"translate(\" + edge.x + \",\" + edge.y + \")\" : \"\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n    .style(\"opacity\", 1)\n    .attr(\"transform\", translate);\n}\n\n},{\"./d3\":7,\"./lodash\":21,\"./util\":27}],24:[function(require,module,exports){\n\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = positionNodes;\n\nfunction positionNodes(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(v) {\n    var node = g.node(v);\n    return \"translate(\" + node.x + \",\" + node.y + \")\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n    .style(\"opacity\", 1)\n    .attr(\"transform\", translate);\n}\n\n},{\"./d3\":7,\"./util\":27}],25:[function(require,module,exports){\nvar _ = require(\"./lodash\"),\n    layout = require(\"./dagre\").layout;\n\nmodule.exports = render;\n\n// This design is based on http://bost.ocks.org/mike/chart/.\nfunction render() {\n  var createNodes = require(\"./create-nodes\"),\n      createClusters = require(\"./create-clusters\"),\n      createEdgeLabels = require(\"./create-edge-labels\"),\n      createEdgePaths = require(\"./create-edge-paths\"),\n      positionNodes = require(\"./position-nodes\"),\n      positionEdgeLabels = require(\"./position-edge-labels\"),\n      positionClusters = require(\"./position-clusters\"),\n      shapes = require(\"./shapes\"),\n      arrows = require(\"./arrows\");\n\n  var fn = function(svg, g) {\n    preProcessGraph(g);\n\n    var outputGroup = createOrSelectGroup(svg, \"output\"),\n        clustersGroup = createOrSelectGroup(outputGroup, \"clusters\"),\n        edgePathsGroup = createOrSelectGroup(outputGroup, \"edgePaths\"),\n        edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, \"edgeLabels\"), g),\n        nodes = createNodes(createOrSelectGroup(outputGroup, \"nodes\"), g, shapes);\n\n    layout(g);\n\n    positionNodes(nodes, g);\n    positionEdgeLabels(edgeLabels, g);\n    createEdgePaths(edgePathsGroup, g, arrows);\n\n    var clusters = createClusters(clustersGroup, g);\n    positionClusters(clusters, g);\n\n    postProcessGraph(g);\n  };\n\n  fn.createNodes = function(value) {\n    if (!arguments.length) return createNodes;\n    createNodes = value;\n    return fn;\n  };\n\n  fn.createClusters = function(value) {\n    if (!arguments.length) return createClusters;\n    createClusters = value;\n    return fn;\n  };\n\n  fn.createEdgeLabels = function(value) {\n    if (!arguments.length) return createEdgeLabels;\n    createEdgeLabels = value;\n    return fn;\n  };\n\n  fn.createEdgePaths = function(value) {\n    if (!arguments.length) return createEdgePaths;\n    createEdgePaths = value;\n    return fn;\n  };\n\n  fn.shapes = function(value) {\n    if (!arguments.length) return shapes;\n    shapes = value;\n    return fn;\n  };\n\n  fn.arrows = function(value) {\n    if (!arguments.length) return arrows;\n    arrows = value;\n    return fn;\n  };\n\n  return fn;\n}\n\nvar NODE_DEFAULT_ATTRS = {\n  paddingLeft: 10,\n  paddingRight: 10,\n  paddingTop: 10,\n  paddingBottom: 10,\n  rx: 0,\n  ry: 0,\n  shape: \"rect\"\n};\n\nvar EDGE_DEFAULT_ATTRS = {\n  arrowhead: \"normal\",\n  lineInterpolate: \"linear\"\n};\n\nfunction preProcessGraph(g) {\n  g.nodes().forEach(function(v) {\n    var node = g.node(v);\n    if (!_.has(node, \"label\") && !g.children(v).length) { node.label = v; }\n\n    if (_.has(node, \"paddingX\")) {\n      _.defaults(node, {\n        paddingLeft: node.paddingX,\n        paddingRight: node.paddingX\n      });\n    }\n\n    if (_.has(node, \"paddingY\")) {\n      _.defaults(node, {\n        paddingTop: node.paddingY,\n        paddingBottom: node.paddingY\n      });\n    }\n\n    if (_.has(node, \"padding\")) {\n      _.defaults(node, {\n        paddingLeft: node.padding,\n        paddingRight: node.padding,\n        paddingTop: node.padding,\n        paddingBottom: node.padding\n      });\n    }\n\n    _.defaults(node, NODE_DEFAULT_ATTRS);\n\n    _.each([\"paddingLeft\", \"paddingRight\", \"paddingTop\", \"paddingBottom\"], function(k) {\n      node[k] = Number(node[k]);\n    });\n\n    // Save dimensions for restore during post-processing\n    if (_.has(node, \"width\")) { node._prevWidth = node.width; }\n    if (_.has(node, \"height\")) { node._prevHeight = node.height; }\n  });\n\n  g.edges().forEach(function(e) {\n    var edge = g.edge(e);\n    if (!_.has(edge, \"label\")) { edge.label = \"\"; }\n    _.defaults(edge, EDGE_DEFAULT_ATTRS);\n  });\n}\n\nfunction postProcessGraph(g) {\n  _.each(g.nodes(), function(v) {\n    var node = g.node(v);\n\n    // Restore original dimensions\n    if (_.has(node, \"_prevWidth\")) {\n      node.width = node._prevWidth;\n    } else {\n      delete node.width;\n    }\n\n    if (_.has(node, \"_prevHeight\")) {\n      node.height = node._prevHeight;\n    } else {\n      delete node.height;\n    }\n\n    delete node._prevWidth;\n    delete node._prevHeight;\n  });\n}\n\nfunction createOrSelectGroup(root, name) {\n  var selection = root.select(\"g.\" + name);\n  if (selection.empty()) {\n    selection = root.append(\"g\").attr(\"class\", name);\n  }\n  return selection;\n}\n\n},{\"./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){\n\"use strict\";\n\nvar intersectRect = require(\"./intersect/intersect-rect\"),\n    intersectEllipse = require(\"./intersect/intersect-ellipse\"),\n    intersectCircle = require(\"./intersect/intersect-circle\"),\n    intersectPolygon = require(\"./intersect/intersect-polygon\");\n\nmodule.exports = {\n  rect: rect,\n  ellipse: ellipse,\n  circle: circle,\n  diamond: diamond\n};\n\nfunction rect(parent, bbox, node) {\n  var shapeSvg = parent.insert(\"rect\", \":first-child\")\n        .attr(\"rx\", node.rx)\n        .attr(\"ry\", node.ry)\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"width\", bbox.width)\n        .attr(\"height\", bbox.height);\n\n  node.intersect = function(point) {\n    return intersectRect(node, point);\n  };\n\n  return shapeSvg;\n}\n\nfunction ellipse(parent, bbox, node) {\n  var rx = bbox.width / 2,\n      ry = bbox.height / 2,\n      shapeSvg = parent.insert(\"ellipse\", \":first-child\")\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"rx\", rx)\n        .attr(\"ry\", ry);\n\n  node.intersect = function(point) {\n    return intersectEllipse(node, rx, ry, point);\n  };\n\n  return shapeSvg;\n}\n\nfunction circle(parent, bbox, node) {\n  var r = Math.max(bbox.width, bbox.height) / 2,\n      shapeSvg = parent.insert(\"circle\", \":first-child\")\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"r\", r);\n\n  node.intersect = function(point) {\n    return intersectCircle(node, r, point);\n  };\n\n  return shapeSvg;\n}\n\n// Circumscribe an ellipse for the bounding box with a diamond shape. I derived\n// the function to calculate the diamond shape from:\n// http://mathforum.org/kb/message.jspa?messageID=3750236\nfunction diamond(parent, bbox, node) {\n  var w = (bbox.width * Math.SQRT2) / 2,\n      h = (bbox.height * Math.SQRT2) / 2,\n      points = [\n        { x:  0, y: -h },\n        { x: -w, y:  0 },\n        { x:  0, y:  h },\n        { x:  w, y:  0 }\n      ],\n      shapeSvg = parent.insert(\"polygon\", \":first-child\")\n        .attr(\"points\", points.map(function(p) { return p.x + \",\" + p.y; }).join(\" \"));\n\n  node.intersect = function(p) {\n    return intersectPolygon(node, points, p);\n  };\n\n  return shapeSvg;\n}\n\n},{\"./intersect/intersect-circle\":11,\"./intersect/intersect-ellipse\":12,\"./intersect/intersect-polygon\":15,\"./intersect/intersect-rect\":16}],27:[function(require,module,exports){\nvar _ = require(\"./lodash\");\n\n// Public utility functions\nmodule.exports = {\n  isSubgraph: isSubgraph,\n  edgeToId: edgeToId,\n  applyStyle: applyStyle,\n  applyClass: applyClass,\n  applyTransition: applyTransition\n};\n\n/*\n * Returns true if the specified node in the graph is a subgraph node. A\n * subgraph node is one that contains other nodes.\n */\nfunction isSubgraph(g, v) {\n  return !!g.children(v).length;\n}\n\nfunction edgeToId(e) {\n  return escapeId(e.v) + \":\" + escapeId(e.w) + \":\" + escapeId(e.name);\n}\n\nvar ID_DELIM = /:/g;\nfunction escapeId(str) {\n  return str ? String(str).replace(ID_DELIM, \"\\\\:\") : \"\";\n}\n\nfunction applyStyle(dom, styleFn) {\n  if (styleFn) {\n    dom.attr(\"style\", styleFn);\n  }\n}\n\nfunction applyClass(dom, classFn, otherClasses) {\n  if (classFn) {\n    dom\n      .attr(\"class\", classFn)\n      .attr(\"class\", otherClasses + \" \" + dom.attr(\"class\"));\n  }\n}\n\nfunction applyTransition(selection, g) {\n  var graph = g.graph();\n\n  if (_.isPlainObject(graph)) {\n    var transition = graph.transition;\n    if (_.isFunction(transition)) {\n      return transition(selection);\n    }\n  }\n\n  return selection;\n}\n\n},{\"./lodash\":21}],28:[function(require,module,exports){\nmodule.exports = \"0.4.17\";\n\n},{}]},{},[1])(1)\n});\n//# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsImxpYi9hcnJvd3MuanMiLCJsaWIvY3JlYXRlLWNsdXN0ZXJzLmpzIiwibGliL2NyZWF0ZS1lZGdlLWxhYmVscy5qcyIsImxpYi9jcmVhdGUtZWRnZS1wYXRocy5qcyIsImxpYi9jcmVhdGUtbm9kZXMuanMiLCJsaWIvZDMuanMiLCJsaWIvZGFncmUuanMiLCJsaWIvZ3JhcGhsaWIuanMiLCJsaWIvaW50ZXJzZWN0L2luZGV4LmpzIiwibGliL2ludGVyc2VjdC9pbnRlcnNlY3QtY2lyY2xlLmpzIiwibGliL2ludGVyc2VjdC9pbnRlcnNlY3QtZWxsaXBzZS5qcyIsImxpYi9pbnRlcnNlY3QvaW50ZXJzZWN0LWxpbmUuanMiLCJsaWIvaW50ZXJzZWN0L2ludGVyc2VjdC1ub2RlLmpzIiwibGliL2ludGVyc2VjdC9pbnRlcnNlY3QtcG9seWdvbi5qcyIsImxpYi9pbnRlcnNlY3QvaW50ZXJzZWN0LXJlY3QuanMiLCJsaWIvbGFiZWwvYWRkLWh0bWwtbGFiZWwuanMiLCJsaWIvbGFiZWwvYWRkLWxhYmVsLmpzIiwibGliL2xhYmVsL2FkZC1zdmctbGFiZWwuanMiLCJsaWIvbGFiZWwvYWRkLXRleHQtbGFiZWwuanMiLCJsaWIvbG9kYXNoLmpzIiwibGliL3Bvc2l0aW9uLWNsdXN0ZXJzLmpzIiwibGliL3Bvc2l0aW9uLWVkZ2UtbGFiZWxzLmpzIiwibGliL3Bvc2l0aW9uLW5vZGVzLmpzIiwibGliL3JlbmRlci5qcyIsImxpYi9zaGFwZXMuanMiLCJsaWIvdXRpbC5qcyIsImxpYi92ZXJzaW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7O0FDRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdktBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxMyBDaHJpcyBQZXR0aXR0XG4gKlxuICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuICpcbiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbiAqXG4gKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuICogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU5cbiAqIFRIRSBTT0ZUV0FSRS5cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSAge1xuICBncmFwaGxpYjogcmVxdWlyZShcIi4vbGliL2dyYXBobGliXCIpLFxuICBkYWdyZTogcmVxdWlyZShcIi4vbGliL2RhZ3JlXCIpLFxuICBpbnRlcnNlY3Q6IHJlcXVpcmUoXCIuL2xpYi9pbnRlcnNlY3RcIiksXG4gIHJlbmRlcjogcmVxdWlyZShcIi4vbGliL3JlbmRlclwiKSxcbiAgdXRpbDogcmVxdWlyZShcIi4vbGliL3V0aWxcIiksXG4gIHZlcnNpb246IHJlcXVpcmUoXCIuL2xpYi92ZXJzaW9uXCIpXG59O1xuIiwidmFyIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCJkZWZhdWx0XCI6IG5vcm1hbCxcbiAgXCJub3JtYWxcIjogbm9ybWFsLFxuICBcInZlZVwiOiB2ZWUsXG4gIFwidW5kaXJlY3RlZFwiOiB1bmRpcmVjdGVkXG59O1xuXG5mdW5jdGlvbiBub3JtYWwocGFyZW50LCBpZCwgZWRnZSwgdHlwZSkge1xuICB2YXIgbWFya2VyID0gcGFyZW50LmFwcGVuZChcIm1hcmtlclwiKVxuICAgIC5hdHRyKFwiaWRcIiwgaWQpXG4gICAgLmF0dHIoXCJ2aWV3Qm94XCIsIFwiMCAwIDEwIDEwXCIpXG4gICAgLmF0dHIoXCJyZWZYXCIsIDkpXG4gICAgLmF0dHIoXCJyZWZZXCIsIDUpXG4gICAgLmF0dHIoXCJtYXJrZXJVbml0c1wiLCBcInN0cm9rZVdpZHRoXCIpXG4gICAgLmF0dHIoXCJtYXJrZXJXaWR0aFwiLCA4KVxuICAgIC5hdHRyKFwibWFya2VySGVpZ2h0XCIsIDYpXG4gICAgLmF0dHIoXCJvcmllbnRcIiwgXCJhdXRvXCIpO1xuXG4gIHZhciBwYXRoID0gbWFya2VyLmFwcGVuZChcInBhdGhcIilcbiAgICAuYXR0cihcImRcIiwgXCJNIDAgMCBMIDEwIDUgTCAwIDEwIHpcIilcbiAgICAuc3R5bGUoXCJzdHJva2Utd2lkdGhcIiwgMSlcbiAgICAuc3R5bGUoXCJzdHJva2UtZGFzaGFycmF5XCIsIFwiMSwwXCIpO1xuICB1dGlsLmFwcGx5U3R5bGUocGF0aCwgZWRnZVt0eXBlICsgXCJTdHlsZVwiXSk7XG4gIGlmIChlZGdlW3R5cGUgKyBcIkNsYXNzXCJdKSB7XG4gICAgcGF0aC5hdHRyKFwiY2xhc3NcIiwgZWRnZVt0eXBlICsgXCJDbGFzc1wiXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmVlKHBhcmVudCwgaWQsIGVkZ2UsIHR5cGUpIHtcbiAgdmFyIG1hcmtlciA9IHBhcmVudC5hcHBlbmQoXCJtYXJrZXJcIilcbiAgICAuYXR0cihcImlkXCIsIGlkKVxuICAgIC5hdHRyKFwidmlld0JveFwiLCBcIjAgMCAxMCAxMFwiKVxuICAgIC5hdHRyKFwicmVmWFwiLCA5KVxuICAgIC5hdHRyKFwicmVmWVwiLCA1KVxuICAgIC5hdHRyKFwibWFya2VyVW5pdHNcIiwgXCJzdHJva2VXaWR0aFwiKVxuICAgIC5hdHRyKFwibWFya2VyV2lkdGhcIiwgOClcbiAgICAuYXR0cihcIm1hcmtlckhlaWdodFwiLCA2KVxuICAgIC5hdHRyKFwib3JpZW50XCIsIFwiYXV0b1wiKTtcblxuICB2YXIgcGF0aCA9IG1hcmtlci5hcHBlbmQoXCJwYXRoXCIpXG4gICAgLmF0dHIoXCJkXCIsIFwiTSAwIDAgTCAxMCA1IEwgMCAxMCBMIDQgNSB6XCIpXG4gICAgLnN0eWxlKFwic3Ryb2tlLXdpZHRoXCIsIDEpXG4gICAgLnN0eWxlKFwic3Ryb2tlLWRhc2hhcnJheVwiLCBcIjEsMFwiKTtcbiAgdXRpbC5hcHBseVN0eWxlKHBhdGgsIGVkZ2VbdHlwZSArIFwiU3R5bGVcIl0pO1xuICBpZiAoZWRnZVt0eXBlICsgXCJDbGFzc1wiXSkge1xuICAgIHBhdGguYXR0cihcImNsYXNzXCIsIGVkZ2VbdHlwZSArIFwiQ2xhc3NcIl0pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHVuZGlyZWN0ZWQocGFyZW50LCBpZCwgZWRnZSwgdHlwZSkge1xuICB2YXIgbWFya2VyID0gcGFyZW50LmFwcGVuZChcIm1hcmtlclwiKVxuICAgIC5hdHRyKFwiaWRcIiwgaWQpXG4gICAgLmF0dHIoXCJ2aWV3Qm94XCIsIFwiMCAwIDEwIDEwXCIpXG4gICAgLmF0dHIoXCJyZWZYXCIsIDkpXG4gICAgLmF0dHIoXCJyZWZZXCIsIDUpXG4gICAgLmF0dHIoXCJtYXJrZXJVbml0c1wiLCBcInN0cm9rZVdpZHRoXCIpXG4gICAgLmF0dHIoXCJtYXJrZXJXaWR0aFwiLCA4KVxuICAgIC5hdHRyKFwibWFya2VySGVpZ2h0XCIsIDYpXG4gICAgLmF0dHIoXCJvcmllbnRcIiwgXCJhdXRvXCIpO1xuXG4gIHZhciBwYXRoID0gbWFya2VyLmFwcGVuZChcInBhdGhcIilcbiAgICAuYXR0cihcImRcIiwgXCJNIDAgNSBMIDEwIDVcIilcbiAgICAuc3R5bGUoXCJzdHJva2Utd2lkdGhcIiwgMSlcbiAgICAuc3R5bGUoXCJzdHJva2UtZGFzaGFycmF5XCIsIFwiMSwwXCIpO1xuICB1dGlsLmFwcGx5U3R5bGUocGF0aCwgZWRnZVt0eXBlICsgXCJTdHlsZVwiXSk7XG4gIGlmIChlZGdlW3R5cGUgKyBcIkNsYXNzXCJdKSB7XG4gICAgcGF0aC5hdHRyKFwiY2xhc3NcIiwgZWRnZVt0eXBlICsgXCJDbGFzc1wiXSk7XG4gIH1cbn1cbiIsInZhciB1dGlsID0gcmVxdWlyZShcIi4vdXRpbFwiKSxcbiAgICBhZGRMYWJlbCA9IHJlcXVpcmUoXCIuL2xhYmVsL2FkZC1sYWJlbFwiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVDbHVzdGVycztcblxuZnVuY3Rpb24gY3JlYXRlQ2x1c3RlcnMoc2VsZWN0aW9uLCBnKSB7XG4gIHZhciBjbHVzdGVycyA9IGcubm9kZXMoKS5maWx0ZXIoZnVuY3Rpb24odikgeyByZXR1cm4gdXRpbC5pc1N1YmdyYXBoKGcsIHYpOyB9KSxcbiAgICAgIHN2Z0NsdXN0ZXJzID0gc2VsZWN0aW9uLnNlbGVjdEFsbChcImcuY2x1c3RlclwiKVxuICAgICAgICAuZGF0YShjbHVzdGVycywgZnVuY3Rpb24odikgeyByZXR1cm4gdjsgfSk7XG5cbiAgc3ZnQ2x1c3RlcnMuc2VsZWN0QWxsKFwiKlwiKS5yZW1vdmUoKTtcbiAgc3ZnQ2x1c3RlcnMuZW50ZXIoKVxuICAgIC5hcHBlbmQoXCJnXCIpXG4gICAgICAuYXR0cihcImNsYXNzXCIsIFwiY2x1c3RlclwiKVxuICAgICAgLmF0dHIoXCJpZFwiLGZ1bmN0aW9uKHYpe1xuICAgICAgICAgIHZhciBub2RlID0gZy5ub2RlKHYpO1xuICAgICAgICAgIHJldHVybiBub2RlLmlkO1xuICAgICAgfSlcbiAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XG5cbiAgdXRpbC5hcHBseVRyYW5zaXRpb24oc3ZnQ2x1c3RlcnMsIGcpXG4gICAgLnN0eWxlKFwib3BhY2l0eVwiLCAxKTtcblxuICBzdmdDbHVzdGVycy5lYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICB2YXIgbm9kZSA9IGcubm9kZSh2KSxcbiAgICAgICAgdGhpc0dyb3VwID0gZDMuc2VsZWN0KHRoaXMpO1xuICAgIGQzLnNlbGVjdCh0aGlzKS5hcHBlbmQoXCJyZWN0XCIpO1xuICAgIHZhciBsYWJlbEdyb3VwID0gdGhpc0dyb3VwLmFwcGVuZChcImdcIikuYXR0cihcImNsYXNzXCIsIFwibGFiZWxcIik7XG4gICAgYWRkTGFiZWwobGFiZWxHcm91cCwgbm9kZSwgbm9kZS5jbHVzdGVyTGFiZWxQb3MpO1xuICB9KTtcblxuICBzdmdDbHVzdGVycy5zZWxlY3RBbGwoXCJyZWN0XCIpLmVhY2goZnVuY3Rpb24oYykge1xuICAgIHZhciBub2RlID0gZy5ub2RlKGMpO1xuICAgIHZhciBkb21DbHVzdGVyID0gZDMuc2VsZWN0KHRoaXMpO1xuICAgIHV0aWwuYXBwbHlTdHlsZShkb21DbHVzdGVyLCBub2RlLnN0eWxlKTtcbiAgfSk7XG5cbiAgdXRpbC5hcHBseVRyYW5zaXRpb24oc3ZnQ2x1c3RlcnMuZXhpdCgpLCBnKVxuICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMClcbiAgICAucmVtb3ZlKCk7XG5cbiAgcmV0dXJuIHN2Z0NsdXN0ZXJzO1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfID0gcmVxdWlyZShcIi4vbG9kYXNoXCIpLFxuICAgIGFkZExhYmVsID0gcmVxdWlyZShcIi4vbGFiZWwvYWRkLWxhYmVsXCIpLFxuICAgIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpLFxuICAgIGQzID0gcmVxdWlyZShcIi4vZDNcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlRWRnZUxhYmVscztcblxuZnVuY3Rpb24gY3JlYXRlRWRnZUxhYmVscyhzZWxlY3Rpb24sIGcpIHtcbiAgdmFyIHN2Z0VkZ2VMYWJlbHMgPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiZy5lZGdlTGFiZWxcIilcbiAgICAuZGF0YShnLmVkZ2VzKCksIGZ1bmN0aW9uKGUpIHsgcmV0dXJuIHV0aWwuZWRnZVRvSWQoZSk7IH0pXG4gICAgLmNsYXNzZWQoXCJ1cGRhdGVcIiwgdHJ1ZSk7XG5cbiAgc3ZnRWRnZUxhYmVscy5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xuICBzdmdFZGdlTGFiZWxzLmVudGVyKClcbiAgICAuYXBwZW5kKFwiZ1wiKVxuICAgICAgLmNsYXNzZWQoXCJlZGdlTGFiZWxcIiwgdHJ1ZSlcbiAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMCk7XG4gIHN2Z0VkZ2VMYWJlbHMuZWFjaChmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVkZ2UgPSBnLmVkZ2UoZSksXG4gICAgICAgIGxhYmVsID0gYWRkTGFiZWwoZDMuc2VsZWN0KHRoaXMpLCBnLmVkZ2UoZSksIDAsIDApLmNsYXNzZWQoXCJsYWJlbFwiLCB0cnVlKSxcbiAgICAgICAgYmJveCA9IGxhYmVsLm5vZGUoKS5nZXRCQm94KCk7XG5cbiAgICBpZiAoZWRnZS5sYWJlbElkKSB7IGxhYmVsLmF0dHIoXCJpZFwiLCBlZGdlLmxhYmVsSWQpOyB9XG4gICAgaWYgKCFfLmhhcyhlZGdlLCBcIndpZHRoXCIpKSB7IGVkZ2Uud2lkdGggPSBiYm94LndpZHRoOyB9XG4gICAgaWYgKCFfLmhhcyhlZGdlLCBcImhlaWdodFwiKSkgeyBlZGdlLmhlaWdodCA9IGJib3guaGVpZ2h0OyB9XG4gIH0pO1xuXG4gIHV0aWwuYXBwbHlUcmFuc2l0aW9uKHN2Z0VkZ2VMYWJlbHMuZXhpdCgpLCBnKVxuICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMClcbiAgICAucmVtb3ZlKCk7XG5cbiAgcmV0dXJuIHN2Z0VkZ2VMYWJlbHM7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIF8gPSByZXF1aXJlKFwiLi9sb2Rhc2hcIiksXG4gICAgaW50ZXJzZWN0Tm9kZSA9IHJlcXVpcmUoXCIuL2ludGVyc2VjdC9pbnRlcnNlY3Qtbm9kZVwiKSxcbiAgICB1dGlsID0gcmVxdWlyZShcIi4vdXRpbFwiKSxcbiAgICBkMyA9IHJlcXVpcmUoXCIuL2QzXCIpO1xubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVFZGdlUGF0aHM7XG5cbmZ1bmN0aW9uIGNyZWF0ZUVkZ2VQYXRocyhzZWxlY3Rpb24sIGcsIGFycm93cykge1xuICB2YXIgc3ZnUGF0aHMgPSBzZWxlY3Rpb24uc2VsZWN0QWxsKFwiZy5lZGdlUGF0aFwiKVxuICAgIC5kYXRhKGcuZWRnZXMoKSwgZnVuY3Rpb24oZSkgeyByZXR1cm4gdXRpbC5lZGdlVG9JZChlKTsgfSlcbiAgICAuY2xhc3NlZChcInVwZGF0ZVwiLCB0cnVlKTtcblxuICBlbnRlcihzdmdQYXRocywgZyk7XG4gIGV4aXQoc3ZnUGF0aHMsIGcpO1xuXG4gIHV0aWwuYXBwbHlUcmFuc2l0aW9uKHN2Z1BhdGhzLCBnKVxuICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMSk7XG5cbiAgLy8gU2F2ZSBET00gZWxlbWVudCBpbiB0aGUgcGF0aCBncm91cCwgYW5kIHNldCBJRCBhbmQgY2xhc3NcbiAgc3ZnUGF0aHMuZWFjaChmdW5jdGlvbihlKSB7XG4gICAgdmFyIGRvbUVkZ2UgPSBkMy5zZWxlY3QodGhpcyk7XG4gICAgdmFyIGVkZ2UgPSBnLmVkZ2UoZSk7XG4gICAgZWRnZS5lbGVtID0gdGhpcztcblxuICAgIGlmIChlZGdlLmlkKSB7XG4gICAgICBkb21FZGdlLmF0dHIoXCJpZFwiLCBlZGdlLmlkKTtcbiAgICB9XG5cbiAgICB1dGlsLmFwcGx5Q2xhc3MoZG9tRWRnZSwgZWRnZVtcImNsYXNzXCJdLFxuICAgICAgKGRvbUVkZ2UuY2xhc3NlZChcInVwZGF0ZVwiKSA/IFwidXBkYXRlIFwiIDogXCJcIikgKyBcImVkZ2VQYXRoXCIpO1xuICB9KTtcblxuICBzdmdQYXRocy5zZWxlY3RBbGwoXCJwYXRoLnBhdGhcIilcbiAgICAuZWFjaChmdW5jdGlvbihlKSB7XG4gICAgICB2YXIgZWRnZSA9IGcuZWRnZShlKTtcbiAgICAgIGVkZ2UuYXJyb3doZWFkSWQgPSBfLnVuaXF1ZUlkKFwiYXJyb3doZWFkXCIpO1xuXG4gICAgICB2YXIgZG9tRWRnZSA9IGQzLnNlbGVjdCh0aGlzKVxuICAgICAgICAuYXR0cihcIm1hcmtlci1lbmRcIiwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJ1cmwoXCIgKyBtYWtlRnJhZ21lbnRSZWYobG9jYXRpb24uaHJlZiwgZWRnZS5hcnJvd2hlYWRJZCkgKyBcIilcIjtcbiAgICAgICAgfSlcbiAgICAgICAgLnN0eWxlKFwiZmlsbFwiLCBcIm5vbmVcIik7XG5cbiAgICAgIHV0aWwuYXBwbHlUcmFuc2l0aW9uKGRvbUVkZ2UsIGcpXG4gICAgICAgIC5hdHRyKFwiZFwiLCBmdW5jdGlvbihlKSB7IHJldHVybiBjYWxjUG9pbnRzKGcsIGUpOyB9KTtcblxuICAgICAgdXRpbC5hcHBseVN0eWxlKGRvbUVkZ2UsIGVkZ2Uuc3R5bGUpO1xuICAgIH0pO1xuXG4gIHN2Z1BhdGhzLnNlbGVjdEFsbChcImRlZnMgKlwiKS5yZW1vdmUoKTtcbiAgc3ZnUGF0aHMuc2VsZWN0QWxsKFwiZGVmc1wiKVxuICAgIC5lYWNoKGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciBlZGdlID0gZy5lZGdlKGUpLFxuICAgICAgICAgIGFycm93aGVhZCA9IGFycm93c1tlZGdlLmFycm93aGVhZF07XG4gICAgICBhcnJvd2hlYWQoZDMuc2VsZWN0KHRoaXMpLCBlZGdlLmFycm93aGVhZElkLCBlZGdlLCBcImFycm93aGVhZFwiKTtcbiAgICB9KTtcblxuICByZXR1cm4gc3ZnUGF0aHM7XG59XG5cbmZ1bmN0aW9uIG1ha2VGcmFnbWVudFJlZih1cmwsIGZyYWdtZW50SWQpIHtcbiAgdmFyIGJhc2VVcmwgPSB1cmwuc3BsaXQoXCIjXCIpWzBdO1xuICByZXR1cm4gYmFzZVVybCArIFwiI1wiICsgZnJhZ21lbnRJZDtcbn1cblxuZnVuY3Rpb24gY2FsY1BvaW50cyhnLCBlKSB7XG4gIHZhciBlZGdlID0gZy5lZGdlKGUpLFxuICAgICAgdGFpbCA9IGcubm9kZShlLnYpLFxuICAgICAgaGVhZCA9IGcubm9kZShlLncpLFxuICAgICAgcG9pbnRzID0gZWRnZS5wb2ludHMuc2xpY2UoMSwgZWRnZS5wb2ludHMubGVuZ3RoIC0gMSk7XG4gIHBvaW50cy51bnNoaWZ0KGludGVyc2VjdE5vZGUodGFpbCwgcG9pbnRzWzBdKSk7XG4gIHBvaW50cy5wdXNoKGludGVyc2VjdE5vZGUoaGVhZCwgcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXSkpO1xuXG4gIHJldHVybiBjcmVhdGVMaW5lKGVkZ2UsIHBvaW50cyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUxpbmUoZWRnZSwgcG9pbnRzKSB7XG4gIHZhciBsaW5lID0gZDMuc3ZnLmxpbmUoKVxuICAgIC54KGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQueDsgfSlcbiAgICAueShmdW5jdGlvbihkKSB7IHJldHVybiBkLnk7IH0pO1xuXG4gIGlmIChfLmhhcyhlZGdlLCBcImxpbmVJbnRlcnBvbGF0ZVwiKSkge1xuICAgIGxpbmUuaW50ZXJwb2xhdGUoZWRnZS5saW5lSW50ZXJwb2xhdGUpO1xuICB9XG5cbiAgaWYgKF8uaGFzKGVkZ2UsIFwibGluZVRlbnNpb25cIikpIHtcbiAgICBsaW5lLnRlbnNpb24oTnVtYmVyKGVkZ2UubGluZVRlbnNpb24pKTtcbiAgfVxuXG4gIHJldHVybiBsaW5lKHBvaW50cyk7XG59XG5cbmZ1bmN0aW9uIGdldENvb3JkcyhlbGVtKSB7XG4gIHZhciBiYm94ID0gZWxlbS5nZXRCQm94KCksXG4gICAgICBtYXRyaXggPSBlbGVtLm93bmVyU1ZHRWxlbWVudC5nZXRTY3JlZW5DVE0oKVxuICAgICAgICAuaW52ZXJzZSgpXG4gICAgICAgIC5tdWx0aXBseShlbGVtLmdldFNjcmVlbkNUTSgpKVxuICAgICAgICAudHJhbnNsYXRlKGJib3gud2lkdGggLyAyLCBiYm94LmhlaWdodCAvIDIpO1xuICByZXR1cm4geyB4OiBtYXRyaXguZSwgeTogbWF0cml4LmYgfTtcbn1cblxuZnVuY3Rpb24gZW50ZXIoc3ZnUGF0aHMsIGcpIHtcbiAgdmFyIHN2Z1BhdGhzRW50ZXIgPSBzdmdQYXRocy5lbnRlcigpXG4gICAgLmFwcGVuZChcImdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJlZGdlUGF0aFwiKVxuICAgICAgLnN0eWxlKFwib3BhY2l0eVwiLCAwKTtcbiAgc3ZnUGF0aHNFbnRlci5hcHBlbmQoXCJwYXRoXCIpXG4gICAgLmF0dHIoXCJjbGFzc1wiLCBcInBhdGhcIilcbiAgICAuYXR0cihcImRcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIGVkZ2UgPSBnLmVkZ2UoZSksXG4gICAgICAgICAgc291cmNlRWxlbSA9IGcubm9kZShlLnYpLmVsZW0sXG4gICAgICAgICAgcG9pbnRzID0gXy5yYW5nZShlZGdlLnBvaW50cy5sZW5ndGgpLm1hcChmdW5jdGlvbigpIHsgcmV0dXJuIGdldENvb3Jkcyhzb3VyY2VFbGVtKTsgfSk7XG4gICAgICByZXR1cm4gY3JlYXRlTGluZShlZGdlLCBwb2ludHMpO1xuICAgIH0pO1xuICBzdmdQYXRoc0VudGVyLmFwcGVuZChcImRlZnNcIik7XG59XG5cbmZ1bmN0aW9uIGV4aXQoc3ZnUGF0aHMsIGcpIHtcbiAgdmFyIHN2Z1BhdGhFeGl0ID0gc3ZnUGF0aHMuZXhpdCgpO1xuICB1dGlsLmFwcGx5VHJhbnNpdGlvbihzdmdQYXRoRXhpdCwgZylcbiAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIDApXG4gICAgLnJlbW92ZSgpO1xuXG4gIHV0aWwuYXBwbHlUcmFuc2l0aW9uKHN2Z1BhdGhFeGl0LnNlbGVjdChcInBhdGgucGF0aFwiKSwgZylcbiAgICAuYXR0cihcImRcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIHNvdXJjZSA9IGcubm9kZShlLnYpO1xuXG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIHZhciBwb2ludHMgPSBfLnJhbmdlKHRoaXMuZ2V0VG90YWxMZW5ndGgoKSkubWFwKGZ1bmN0aW9uKCkgeyByZXR1cm4gc291cmNlOyB9KTtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUxpbmUoe30sIHBvaW50cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZDMuc2VsZWN0KHRoaXMpLmF0dHIoXCJkXCIpO1xuICAgICAgfVxuICAgIH0pO1xufVxuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfID0gcmVxdWlyZShcIi4vbG9kYXNoXCIpLFxuICAgIGFkZExhYmVsID0gcmVxdWlyZShcIi4vbGFiZWwvYWRkLWxhYmVsXCIpLFxuICAgIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpLFxuICAgIGQzID0gcmVxdWlyZShcIi4vZDNcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlTm9kZXM7XG5cbmZ1bmN0aW9uIGNyZWF0ZU5vZGVzKHNlbGVjdGlvbiwgZywgc2hhcGVzKSB7XG4gIHZhciBzaW1wbGVOb2RlcyA9IGcubm9kZXMoKS5maWx0ZXIoZnVuY3Rpb24odikgeyByZXR1cm4gIXV0aWwuaXNTdWJncmFwaChnLCB2KTsgfSk7XG4gIHZhciBzdmdOb2RlcyA9IHNlbGVjdGlvbi5zZWxlY3RBbGwoXCJnLm5vZGVcIilcbiAgICAuZGF0YShzaW1wbGVOb2RlcywgZnVuY3Rpb24odikgeyByZXR1cm4gdjsgfSlcbiAgICAuY2xhc3NlZChcInVwZGF0ZVwiLCB0cnVlKTtcblxuICBzdmdOb2Rlcy5zZWxlY3RBbGwoXCIqXCIpLnJlbW92ZSgpO1xuICBzdmdOb2Rlcy5lbnRlcigpXG4gICAgLmFwcGVuZChcImdcIilcbiAgICAgIC5hdHRyKFwiY2xhc3NcIiwgXCJub2RlXCIpXG4gICAgICAuc3R5bGUoXCJvcGFjaXR5XCIsIDApO1xuICBzdmdOb2Rlcy5lYWNoKGZ1bmN0aW9uKHYpIHtcbiAgICB2YXIgbm9kZSA9IGcubm9kZSh2KSxcbiAgICAgICAgdGhpc0dyb3VwID0gZDMuc2VsZWN0KHRoaXMpLFxuICAgICAgICBsYWJlbEdyb3VwID0gdGhpc0dyb3VwLmFwcGVuZChcImdcIikuYXR0cihcImNsYXNzXCIsIFwibGFiZWxcIiksXG4gICAgICAgIGxhYmVsRG9tID0gYWRkTGFiZWwobGFiZWxHcm91cCwgbm9kZSksXG4gICAgICAgIHNoYXBlID0gc2hhcGVzW25vZGUuc2hhcGVdLFxuICAgICAgICBiYm94ID0gXy5waWNrKGxhYmVsRG9tLm5vZGUoKS5nZXRCQm94KCksIFwid2lkdGhcIiwgXCJoZWlnaHRcIik7XG5cbiAgICBub2RlLmVsZW0gPSB0aGlzO1xuXG4gICAgaWYgKG5vZGUuaWQpIHsgdGhpc0dyb3VwLmF0dHIoXCJpZFwiLCBub2RlLmlkKTsgfVxuICAgIGlmIChub2RlLmxhYmVsSWQpIHsgbGFiZWxHcm91cC5hdHRyKFwiaWRcIiwgbm9kZS5sYWJlbElkKTsgfVxuICAgIHV0aWwuYXBwbHlDbGFzcyh0aGlzR3JvdXAsIG5vZGVbXCJjbGFzc1wiXSxcbiAgICAgICh0aGlzR3JvdXAuY2xhc3NlZChcInVwZGF0ZVwiKSA/IFwidXBkYXRlIFwiIDogXCJcIikgKyBcIm5vZGVcIik7XG5cbiAgICBpZiAoXy5oYXMobm9kZSwgXCJ3aWR0aFwiKSkgeyBiYm94LndpZHRoID0gbm9kZS53aWR0aDsgfVxuICAgIGlmIChfLmhhcyhub2RlLCBcImhlaWdodFwiKSkgeyBiYm94LmhlaWdodCA9IG5vZGUuaGVpZ2h0OyB9XG5cbiAgICBiYm94LndpZHRoICs9IG5vZGUucGFkZGluZ0xlZnQgKyBub2RlLnBhZGRpbmdSaWdodDtcbiAgICBiYm94LmhlaWdodCArPSBub2RlLnBhZGRpbmdUb3AgKyBub2RlLnBhZGRpbmdCb3R0b207XG4gICAgbGFiZWxHcm91cC5hdHRyKFwidHJhbnNmb3JtXCIsIFwidHJhbnNsYXRlKFwiICtcbiAgICAgICgobm9kZS5wYWRkaW5nTGVmdCAtIG5vZGUucGFkZGluZ1JpZ2h0KSAvIDIpICsgXCIsXCIgK1xuICAgICAgKChub2RlLnBhZGRpbmdUb3AgLSBub2RlLnBhZGRpbmdCb3R0b20pIC8gMikgKyBcIilcIik7XG5cbiAgICB2YXIgc2hhcGVTdmcgPSBzaGFwZShkMy5zZWxlY3QodGhpcyksIGJib3gsIG5vZGUpO1xuICAgIHV0aWwuYXBwbHlTdHlsZShzaGFwZVN2Zywgbm9kZS5zdHlsZSk7XG5cbiAgICB2YXIgc2hhcGVCQm94ID0gc2hhcGVTdmcubm9kZSgpLmdldEJCb3goKTtcbiAgICBub2RlLndpZHRoID0gc2hhcGVCQm94LndpZHRoO1xuICAgIG5vZGUuaGVpZ2h0ID0gc2hhcGVCQm94LmhlaWdodDtcbiAgfSk7XG5cbiAgdXRpbC5hcHBseVRyYW5zaXRpb24oc3ZnTm9kZXMuZXhpdCgpLCBnKVxuICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMClcbiAgICAucmVtb3ZlKCk7XG5cbiAgcmV0dXJuIHN2Z05vZGVzO1xufVxuIiwiLy8gU3R1YiB0byBnZXQgRDMgZWl0aGVyIHZpYSBOUE0gb3IgZnJvbSB0aGUgZ2xvYmFsIG9iamVjdFxubW9kdWxlLmV4cG9ydHMgPSB3aW5kb3cuZDM7XG4iLCIvKiBnbG9iYWwgd2luZG93ICovXG5cbnZhciBkYWdyZTtcblxuaWYgKHJlcXVpcmUpIHtcbiAgdHJ5IHtcbiAgICBkYWdyZSA9IHJlcXVpcmUoXCJkYWdyZVwiKTtcbiAgfSBjYXRjaCAoZSkge31cbn1cblxuaWYgKCFkYWdyZSkge1xuICBkYWdyZSA9IHdpbmRvdy5kYWdyZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBkYWdyZTtcbiIsIi8qIGdsb2JhbCB3aW5kb3cgKi9cblxudmFyIGdyYXBobGliO1xuXG5pZiAocmVxdWlyZSkge1xuICB0cnkge1xuICAgIGdyYXBobGliID0gcmVxdWlyZShcImdyYXBobGliXCIpO1xuICB9IGNhdGNoIChlKSB7fVxufVxuXG5pZiAoIWdyYXBobGliKSB7XG4gIGdyYXBobGliID0gd2luZG93LmdyYXBobGliO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdyYXBobGliO1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIG5vZGU6IHJlcXVpcmUoXCIuL2ludGVyc2VjdC1ub2RlXCIpLFxuICBjaXJjbGU6IHJlcXVpcmUoXCIuL2ludGVyc2VjdC1jaXJjbGVcIiksXG4gIGVsbGlwc2U6IHJlcXVpcmUoXCIuL2ludGVyc2VjdC1lbGxpcHNlXCIpLFxuICBwb2x5Z29uOiByZXF1aXJlKFwiLi9pbnRlcnNlY3QtcG9seWdvblwiKSxcbiAgcmVjdDogcmVxdWlyZShcIi4vaW50ZXJzZWN0LXJlY3RcIilcbn07XG4iLCJ2YXIgaW50ZXJzZWN0RWxsaXBzZSA9IHJlcXVpcmUoXCIuL2ludGVyc2VjdC1lbGxpcHNlXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGludGVyc2VjdENpcmNsZTtcblxuZnVuY3Rpb24gaW50ZXJzZWN0Q2lyY2xlKG5vZGUsIHJ4LCBwb2ludCkge1xuICByZXR1cm4gaW50ZXJzZWN0RWxsaXBzZShub2RlLCByeCwgcngsIHBvaW50KTtcbn1cbiIsIm1vZHVsZS5leHBvcnRzID0gaW50ZXJzZWN0RWxsaXBzZTtcblxuZnVuY3Rpb24gaW50ZXJzZWN0RWxsaXBzZShub2RlLCByeCwgcnksIHBvaW50KSB7XG4gIC8vIEZvcm11bGFlIGZyb206IGh0dHA6Ly9tYXRod29ybGQud29sZnJhbS5jb20vRWxsaXBzZS1MaW5lSW50ZXJzZWN0aW9uLmh0bWxcblxuICB2YXIgY3ggPSBub2RlLng7XG4gIHZhciBjeSA9IG5vZGUueTtcblxuICB2YXIgcHggPSBjeCAtIHBvaW50Lng7XG4gIHZhciBweSA9IGN5IC0gcG9pbnQueTtcblxuICB2YXIgZGV0ID0gTWF0aC5zcXJ0KHJ4ICogcnggKiBweSAqIHB5ICsgcnkgKiByeSAqIHB4ICogcHgpO1xuXG4gIHZhciBkeCA9IE1hdGguYWJzKHJ4ICogcnkgKiBweCAvIGRldCk7XG4gIGlmIChwb2ludC54IDwgY3gpIHtcbiAgICBkeCA9IC1keDtcbiAgfVxuICB2YXIgZHkgPSBNYXRoLmFicyhyeCAqIHJ5ICogcHkgLyBkZXQpO1xuICBpZiAocG9pbnQueSA8IGN5KSB7XG4gICAgZHkgPSAtZHk7XG4gIH1cblxuICByZXR1cm4ge3g6IGN4ICsgZHgsIHk6IGN5ICsgZHl9O1xufVxuXG4iLCJtb2R1bGUuZXhwb3J0cyA9IGludGVyc2VjdExpbmU7XG5cbi8qXG4gKiBSZXR1cm5zIHRoZSBwb2ludCBhdCB3aGljaCB0d28gbGluZXMsIHAgYW5kIHEsIGludGVyc2VjdCBvciByZXR1cm5zXG4gKiB1bmRlZmluZWQgaWYgdGhleSBkbyBub3QgaW50ZXJzZWN0LlxuICovXG5mdW5jdGlvbiBpbnRlcnNlY3RMaW5lKHAxLCBwMiwgcTEsIHEyKSB7XG4gIC8vIEFsZ29yaXRobSBmcm9tIEouIEF2cm8sIChlZC4pIEdyYXBoaWNzIEdlbXMsIE5vIDIsIE1vcmdhbiBLYXVmbWFubiwgMTk5NCxcbiAgLy8gcDcgYW5kIHA0NzMuXG5cbiAgdmFyIGExLCBhMiwgYjEsIGIyLCBjMSwgYzI7XG4gIHZhciByMSwgcjIgLCByMywgcjQ7XG4gIHZhciBkZW5vbSwgb2Zmc2V0LCBudW07XG4gIHZhciB4LCB5O1xuXG4gIC8vIENvbXB1dGUgYTEsIGIxLCBjMSwgd2hlcmUgbGluZSBqb2luaW5nIHBvaW50cyAxIGFuZCAyIGlzIEYoeCx5KSA9IGExIHggK1xuICAvLyBiMSB5ICsgYzEgPSAwLlxuICBhMSA9IHAyLnkgLSBwMS55O1xuICBiMSA9IHAxLnggLSBwMi54O1xuICBjMSA9IChwMi54ICogcDEueSkgLSAocDEueCAqIHAyLnkpO1xuXG4gIC8vIENvbXB1dGUgcjMgYW5kIHI0LlxuICByMyA9ICgoYTEgKiBxMS54KSArIChiMSAqIHExLnkpICsgYzEpO1xuICByNCA9ICgoYTEgKiBxMi54KSArIChiMSAqIHEyLnkpICsgYzEpO1xuXG4gIC8vIENoZWNrIHNpZ25zIG9mIHIzIGFuZCByNC4gSWYgYm90aCBwb2ludCAzIGFuZCBwb2ludCA0IGxpZSBvblxuICAvLyBzYW1lIHNpZGUgb2YgbGluZSAxLCB0aGUgbGluZSBzZWdtZW50cyBkbyBub3QgaW50ZXJzZWN0LlxuICBpZiAoKHIzICE9PSAwKSAmJiAocjQgIT09IDApICYmIHNhbWVTaWduKHIzLCByNCkpIHtcbiAgICByZXR1cm4gLypET05UX0lOVEVSU0VDVCovO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSBhMiwgYjIsIGMyIHdoZXJlIGxpbmUgam9pbmluZyBwb2ludHMgMyBhbmQgNCBpcyBHKHgseSkgPSBhMiB4ICsgYjIgeSArIGMyID0gMFxuICBhMiA9IHEyLnkgLSBxMS55O1xuICBiMiA9IHExLnggLSBxMi54O1xuICBjMiA9IChxMi54ICogcTEueSkgLSAocTEueCAqIHEyLnkpO1xuXG4gIC8vIENvbXB1dGUgcjEgYW5kIHIyXG4gIHIxID0gKGEyICogcDEueCkgKyAoYjIgKiBwMS55KSArIGMyO1xuICByMiA9IChhMiAqIHAyLngpICsgKGIyICogcDIueSkgKyBjMjtcblxuICAvLyBDaGVjayBzaWducyBvZiByMSBhbmQgcjIuIElmIGJvdGggcG9pbnQgMSBhbmQgcG9pbnQgMiBsaWVcbiAgLy8gb24gc2FtZSBzaWRlIG9mIHNlY29uZCBsaW5lIHNlZ21lbnQsIHRoZSBsaW5lIHNlZ21lbnRzIGRvXG4gIC8vIG5vdCBpbnRlcnNlY3QuXG4gIGlmICgocjEgIT09IDApICYmIChyMiAhPT0gMCkgJiYgKHNhbWVTaWduKHIxLCByMikpKSB7XG4gICAgcmV0dXJuIC8qRE9OVF9JTlRFUlNFQ1QqLztcbiAgfVxuXG4gIC8vIExpbmUgc2VnbWVudHMgaW50ZXJzZWN0OiBjb21wdXRlIGludGVyc2VjdGlvbiBwb2ludC5cbiAgZGVub20gPSAoYTEgKiBiMikgLSAoYTIgKiBiMSk7XG4gIGlmIChkZW5vbSA9PT0gMCkge1xuICAgIHJldHVybiAvKkNPTExJTkVBUiovO1xuICB9XG5cbiAgb2Zmc2V0ID0gTWF0aC5hYnMoZGVub20gLyAyKTtcblxuICAvLyBUaGUgZGVub20vMiBpcyB0byBnZXQgcm91bmRpbmcgaW5zdGVhZCBvZiB0cnVuY2F0aW5nLiBJdFxuICAvLyBpcyBhZGRlZCBvciBzdWJ0cmFjdGVkIHRvIHRoZSBudW1lcmF0b3IsIGRlcGVuZGluZyB1cG9uIHRoZVxuICAvLyBzaWduIG9mIHRoZSBudW1lcmF0b3IuXG4gIG51bSA9IChiMSAqIGMyKSAtIChiMiAqIGMxKTtcbiAgeCA9IChudW0gPCAwKSA/ICgobnVtIC0gb2Zmc2V0KSAvIGRlbm9tKSA6ICgobnVtICsgb2Zmc2V0KSAvIGRlbm9tKTtcblxuICBudW0gPSAoYTIgKiBjMSkgLSAoYTEgKiBjMik7XG4gIHkgPSAobnVtIDwgMCkgPyAoKG51bSAtIG9mZnNldCkgLyBkZW5vbSkgOiAoKG51bSArIG9mZnNldCkgLyBkZW5vbSk7XG5cbiAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xufVxuXG5mdW5jdGlvbiBzYW1lU2lnbihyMSwgcjIpIHtcbiAgcmV0dXJuIHIxICogcjIgPiAwO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBpbnRlcnNlY3ROb2RlO1xuXG5mdW5jdGlvbiBpbnRlcnNlY3ROb2RlKG5vZGUsIHBvaW50KSB7XG4gIHJldHVybiBub2RlLmludGVyc2VjdChwb2ludCk7XG59XG4iLCJ2YXIgaW50ZXJzZWN0TGluZSA9IHJlcXVpcmUoXCIuL2ludGVyc2VjdC1saW5lXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGludGVyc2VjdFBvbHlnb247XG5cbi8qXG4gKiBSZXR1cm5zIHRoZSBwb2ludCAoe3gsIHl9KSBhdCB3aGljaCB0aGUgcG9pbnQgYXJndW1lbnQgaW50ZXJzZWN0cyB3aXRoIHRoZVxuICogbm9kZSBhcmd1bWVudCBhc3N1bWluZyB0aGF0IGl0IGhhcyB0aGUgc2hhcGUgc3BlY2lmaWVkIGJ5IHBvbHlnb24uXG4gKi9cbmZ1bmN0aW9uIGludGVyc2VjdFBvbHlnb24obm9kZSwgcG9seVBvaW50cywgcG9pbnQpIHtcbiAgdmFyIHgxID0gbm9kZS54O1xuICB2YXIgeTEgPSBub2RlLnk7XG5cbiAgdmFyIGludGVyc2VjdGlvbnMgPSBbXTtcblxuICB2YXIgbWluWCA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSxcbiAgICAgIG1pblkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gIHBvbHlQb2ludHMuZm9yRWFjaChmdW5jdGlvbihlbnRyeSkge1xuICAgIG1pblggPSBNYXRoLm1pbihtaW5YLCBlbnRyeS54KTtcbiAgICBtaW5ZID0gTWF0aC5taW4obWluWSwgZW50cnkueSk7XG4gIH0pO1xuXG4gIHZhciBsZWZ0ID0geDEgLSBub2RlLndpZHRoIC8gMiAtIG1pblg7XG4gIHZhciB0b3AgPSAgeTEgLSBub2RlLmhlaWdodCAvIDIgLSBtaW5ZO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgcG9seVBvaW50cy5sZW5ndGg7IGkrKykge1xuICAgIHZhciBwMSA9IHBvbHlQb2ludHNbaV07XG4gICAgdmFyIHAyID0gcG9seVBvaW50c1tpIDwgcG9seVBvaW50cy5sZW5ndGggLSAxID8gaSArIDEgOiAwXTtcbiAgICB2YXIgaW50ZXJzZWN0ID0gaW50ZXJzZWN0TGluZShub2RlLCBwb2ludCxcbiAgICAgIHt4OiBsZWZ0ICsgcDEueCwgeTogdG9wICsgcDEueX0sIHt4OiBsZWZ0ICsgcDIueCwgeTogdG9wICsgcDIueX0pO1xuICAgIGlmIChpbnRlcnNlY3QpIHtcbiAgICAgIGludGVyc2VjdGlvbnMucHVzaChpbnRlcnNlY3QpO1xuICAgIH1cbiAgfVxuXG4gIGlmICghaW50ZXJzZWN0aW9ucy5sZW5ndGgpIHtcbiAgICBjb25zb2xlLmxvZyhcIk5PIElOVEVSU0VDVElPTiBGT1VORCwgUkVUVVJOIE5PREUgQ0VOVEVSXCIsIG5vZGUpO1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgaWYgKGludGVyc2VjdGlvbnMubGVuZ3RoID4gMSkge1xuICAgIC8vIE1vcmUgaW50ZXJzZWN0aW9ucywgZmluZCB0aGUgb25lIG5lYXJlc3QgdG8gZWRnZSBlbmQgcG9pbnRcbiAgICBpbnRlcnNlY3Rpb25zLnNvcnQoZnVuY3Rpb24ocCwgcSkge1xuICAgICAgdmFyIHBkeCA9IHAueCAtIHBvaW50LngsXG4gICAgICAgICAgcGR5ID0gcC55IC0gcG9pbnQueSxcbiAgICAgICAgICBkaXN0cCA9IE1hdGguc3FydChwZHggKiBwZHggKyBwZHkgKiBwZHkpLFxuXG4gICAgICAgICAgcWR4ID0gcS54IC0gcG9pbnQueCxcbiAgICAgICAgICBxZHkgPSBxLnkgLSBwb2ludC55LFxuICAgICAgICAgIGRpc3RxID0gTWF0aC5zcXJ0KHFkeCAqIHFkeCArIHFkeSAqIHFkeSk7XG5cbiAgICAgIHJldHVybiAoZGlzdHAgPCBkaXN0cSkgPyAtMSA6IChkaXN0cCA9PT0gZGlzdHEgPyAwIDogMSk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIGludGVyc2VjdGlvbnNbMF07XG59XG4iLCJtb2R1bGUuZXhwb3J0cyA9IGludGVyc2VjdFJlY3Q7XG5cbmZ1bmN0aW9uIGludGVyc2VjdFJlY3Qobm9kZSwgcG9pbnQpIHtcbiAgdmFyIHggPSBub2RlLng7XG4gIHZhciB5ID0gbm9kZS55O1xuXG4gIC8vIFJlY3RhbmdsZSBpbnRlcnNlY3Rpb24gYWxnb3JpdGhtIGZyb206XG4gIC8vIGh0dHA6Ly9tYXRoLnN0YWNrZXhjaGFuZ2UuY29tL3F1ZXN0aW9ucy8xMDgxMTMvZmluZC1lZGdlLWJldHdlZW4tdHdvLWJveGVzXG4gIHZhciBkeCA9IHBvaW50LnggLSB4O1xuICB2YXIgZHkgPSBwb2ludC55IC0geTtcbiAgdmFyIHcgPSBub2RlLndpZHRoIC8gMjtcbiAgdmFyIGggPSBub2RlLmhlaWdodCAvIDI7XG5cbiAgdmFyIHN4LCBzeTtcbiAgaWYgKE1hdGguYWJzKGR5KSAqIHcgPiBNYXRoLmFicyhkeCkgKiBoKSB7XG4gICAgLy8gSW50ZXJzZWN0aW9uIGlzIHRvcCBvciBib3R0b20gb2YgcmVjdC5cbiAgICBpZiAoZHkgPCAwKSB7XG4gICAgICBoID0gLWg7XG4gICAgfVxuICAgIHN4ID0gZHkgPT09IDAgPyAwIDogaCAqIGR4IC8gZHk7XG4gICAgc3kgPSBoO1xuICB9IGVsc2Uge1xuICAgIC8vIEludGVyc2VjdGlvbiBpcyBsZWZ0IG9yIHJpZ2h0IG9mIHJlY3QuXG4gICAgaWYgKGR4IDwgMCkge1xuICAgICAgdyA9IC13O1xuICAgIH1cbiAgICBzeCA9IHc7XG4gICAgc3kgPSBkeCA9PT0gMCA/IDAgOiB3ICogZHkgLyBkeDtcbiAgfVxuXG4gIHJldHVybiB7eDogeCArIHN4LCB5OiB5ICsgc3l9O1xufVxuIiwidmFyIHV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBhZGRIdG1sTGFiZWw7XG5cbmZ1bmN0aW9uIGFkZEh0bWxMYWJlbChyb290LCBub2RlKSB7XG4gIHZhciBmbyA9IHJvb3RcbiAgICAuYXBwZW5kKFwiZm9yZWlnbk9iamVjdFwiKVxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBcIjEwMDAwMFwiKTtcblxuICB2YXIgZGl2ID0gZm9cbiAgICAuYXBwZW5kKFwieGh0bWw6ZGl2XCIpO1xuICBkaXYuYXR0cihcInhtbG5zXCIsIFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiKTtcblxuICB2YXIgbGFiZWwgPSBub2RlLmxhYmVsO1xuICBzd2l0Y2godHlwZW9mIGxhYmVsKSB7XG4gICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICBkaXYuaW5zZXJ0KGxhYmVsKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJvYmplY3RcIjpcbiAgICAgIC8vIEN1cnJlbnRseSB3ZSBhc3N1bWUgdGhpcyBpcyBhIERPTSBvYmplY3QuXG4gICAgICBkaXYuaW5zZXJ0KGZ1bmN0aW9uKCkgeyByZXR1cm4gbGFiZWw7IH0pO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDogZGl2Lmh0bWwobGFiZWwpO1xuICB9XG5cbiAgdXRpbC5hcHBseVN0eWxlKGRpdiwgbm9kZS5sYWJlbFN0eWxlKTtcbiAgZGl2LnN0eWxlKFwiZGlzcGxheVwiLCBcImlubGluZS1ibG9ja1wiKTtcbiAgLy8gRml4IGZvciBmaXJlZm94XG4gIGRpdi5zdHlsZShcIndoaXRlLXNwYWNlXCIsIFwibm93cmFwXCIpO1xuXG4gIHZhciBjbGllbnQgPSBkaXZbMF1bMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIGZvXG4gICAgLmF0dHIoXCJ3aWR0aFwiLCBjbGllbnQud2lkdGgpXG4gICAgLmF0dHIoXCJoZWlnaHRcIiwgY2xpZW50LmhlaWdodCk7IFxuXG4gIHJldHVybiBmbztcbn1cbiIsInZhciBhZGRUZXh0TGFiZWwgPSByZXF1aXJlKFwiLi9hZGQtdGV4dC1sYWJlbFwiKSxcbiAgICBhZGRIdG1sTGFiZWwgPSByZXF1aXJlKFwiLi9hZGQtaHRtbC1sYWJlbFwiKSxcbiAgICBhZGRTVkdMYWJlbCAgPSByZXF1aXJlKFwiLi9hZGQtc3ZnLWxhYmVsXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGFkZExhYmVsO1xuXG5mdW5jdGlvbiBhZGRMYWJlbChyb290LCBub2RlLCBsb2NhdGlvbikge1xuICB2YXIgbGFiZWwgPSBub2RlLmxhYmVsO1xuICB2YXIgbGFiZWxTdmcgPSByb290LmFwcGVuZChcImdcIik7XG5cbiAgLy8gQWxsb3cgdGhlIGxhYmVsIHRvIGJlIGEgc3RyaW5nLCBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIERPTSBlbGVtZW50LCBvclxuICAvLyBhIERPTSBlbGVtZW50IGl0c2VsZi5cbiAgaWYgKG5vZGUubGFiZWxUeXBlID09PSBcInN2Z1wiKSB7XG4gICAgYWRkU1ZHTGFiZWwobGFiZWxTdmcsIG5vZGUpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBsYWJlbCAhPT0gXCJzdHJpbmdcIiB8fCBub2RlLmxhYmVsVHlwZSA9PT0gXCJodG1sXCIpIHtcbiAgICBhZGRIdG1sTGFiZWwobGFiZWxTdmcsIG5vZGUpO1xuICB9IGVsc2Uge1xuICAgIGFkZFRleHRMYWJlbChsYWJlbFN2Zywgbm9kZSk7XG4gIH1cblxuICB2YXIgbGFiZWxCQm94ID0gbGFiZWxTdmcubm9kZSgpLmdldEJCb3goKTtcbiAgdmFyIHk7XG4gIHN3aXRjaChsb2NhdGlvbikge1xuICAgIGNhc2UgXCJ0b3BcIjpcbiAgICAgIHkgPSAoLW5vZGUuaGVpZ2h0IC8gMik7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwiYm90dG9tXCI6XG4gICAgICB5ID0gKG5vZGUuaGVpZ2h0IC8gMikgLSBsYWJlbEJCb3guaGVpZ2h0O1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHkgPSAoLWxhYmVsQkJveC5oZWlnaHQgLyAyKTtcbiAgfVxuICBsYWJlbFN2Zy5hdHRyKFwidHJhbnNmb3JtXCIsXG4gICAgICAgICAgICAgICAgXCJ0cmFuc2xhdGUoXCIgKyAoLWxhYmVsQkJveC53aWR0aCAvIDIpICsgXCIsXCIgKyB5ICsgXCIpXCIpO1xuXG4gIHJldHVybiBsYWJlbFN2Zztcbn1cbiIsInZhciB1dGlsID0gcmVxdWlyZShcIi4uL3V0aWxcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gYWRkU1ZHTGFiZWw7XG5cbmZ1bmN0aW9uIGFkZFNWR0xhYmVsKHJvb3QsIG5vZGUpIHtcbiAgdmFyIGRvbU5vZGUgPSByb290O1xuXG4gIGRvbU5vZGUubm9kZSgpLmFwcGVuZENoaWxkKG5vZGUubGFiZWwpO1xuXG4gIHV0aWwuYXBwbHlTdHlsZShkb21Ob2RlLCBub2RlLmxhYmVsU3R5bGUpO1xuXG4gIHJldHVybiBkb21Ob2RlO1xufVxuIiwidmFyIHV0aWwgPSByZXF1aXJlKFwiLi4vdXRpbFwiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBhZGRUZXh0TGFiZWw7XG5cbi8qXG4gKiBBdHRhY2hlcyBhIHRleHQgbGFiZWwgdG8gdGhlIHNwZWNpZmllZCByb290LiBIYW5kbGVzIGVzY2FwZSBzZXF1ZW5jZXMuXG4gKi9cbmZ1bmN0aW9uIGFkZFRleHRMYWJlbChyb290LCBub2RlKSB7XG4gIHZhciBkb21Ob2RlID0gcm9vdC5hcHBlbmQoXCJ0ZXh0XCIpO1xuXG4gIHZhciBsaW5lcyA9IHByb2Nlc3NFc2NhcGVTZXF1ZW5jZXMobm9kZS5sYWJlbCkuc3BsaXQoXCJcXG5cIik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyBpKyspIHtcbiAgICBkb21Ob2RlXG4gICAgICAuYXBwZW5kKFwidHNwYW5cIilcbiAgICAgICAgLmF0dHIoXCJ4bWw6c3BhY2VcIiwgXCJwcmVzZXJ2ZVwiKVxuICAgICAgICAuYXR0cihcImR5XCIsIFwiMWVtXCIpXG4gICAgICAgIC5hdHRyKFwieFwiLCBcIjFcIilcbiAgICAgICAgLnRleHQobGluZXNbaV0pO1xuICB9XG5cbiAgdXRpbC5hcHBseVN0eWxlKGRvbU5vZGUsIG5vZGUubGFiZWxTdHlsZSk7XG5cbiAgcmV0dXJuIGRvbU5vZGU7XG59XG5cbmZ1bmN0aW9uIHByb2Nlc3NFc2NhcGVTZXF1ZW5jZXModGV4dCkge1xuICB2YXIgbmV3VGV4dCA9IFwiXCIsXG4gICAgICBlc2NhcGVkID0gZmFsc2UsXG4gICAgICBjaDtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB0ZXh0Lmxlbmd0aDsgKytpKSB7XG4gICAgY2ggPSB0ZXh0W2ldO1xuICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICBzd2l0Y2goY2gpIHtcbiAgICAgICAgY2FzZSBcIm5cIjogbmV3VGV4dCArPSBcIlxcblwiOyBicmVhaztcbiAgICAgICAgZGVmYXVsdDogbmV3VGV4dCArPSBjaDtcbiAgICAgIH1cbiAgICAgIGVzY2FwZWQgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGNoID09PSBcIlxcXFxcIikge1xuICAgICAgZXNjYXBlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld1RleHQgKz0gY2g7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXdUZXh0O1xufVxuIiwiLyogZ2xvYmFsIHdpbmRvdyAqL1xuXG52YXIgbG9kYXNoO1xuXG5pZiAocmVxdWlyZSkge1xuICB0cnkge1xuICAgIGxvZGFzaCA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XG4gIH0gY2F0Y2ggKGUpIHt9XG59XG5cbmlmICghbG9kYXNoKSB7XG4gIGxvZGFzaCA9IHdpbmRvdy5fO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIiksXG4gICAgZDMgPSByZXF1aXJlKFwiLi9kM1wiKTtcblxubW9kdWxlLmV4cG9ydHMgPSBwb3NpdGlvbkNsdXN0ZXJzO1xuXG5mdW5jdGlvbiBwb3NpdGlvbkNsdXN0ZXJzKHNlbGVjdGlvbiwgZykge1xuICB2YXIgY3JlYXRlZCA9IHNlbGVjdGlvbi5maWx0ZXIoZnVuY3Rpb24oKSB7IHJldHVybiAhZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoXCJ1cGRhdGVcIik7IH0pO1xuXG4gIGZ1bmN0aW9uIHRyYW5zbGF0ZSh2KSB7XG4gICAgdmFyIG5vZGUgPSBnLm5vZGUodik7XG4gICAgcmV0dXJuIFwidHJhbnNsYXRlKFwiICsgbm9kZS54ICsgXCIsXCIgKyBub2RlLnkgKyBcIilcIjtcbiAgfVxuXG4gIGNyZWF0ZWQuYXR0cihcInRyYW5zZm9ybVwiLCB0cmFuc2xhdGUpO1xuXG4gIHV0aWwuYXBwbHlUcmFuc2l0aW9uKHNlbGVjdGlvbiwgZylcbiAgICAgIC5zdHlsZShcIm9wYWNpdHlcIiwgMSlcbiAgICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIHRyYW5zbGF0ZSk7XG5cbiAgdXRpbC5hcHBseVRyYW5zaXRpb24oY3JlYXRlZC5zZWxlY3RBbGwoXCJyZWN0XCIpLCBnKVxuICAgICAgLmF0dHIoXCJ3aWR0aFwiLCBmdW5jdGlvbih2KSB7IHJldHVybiBnLm5vZGUodikud2lkdGg7IH0pXG4gICAgICAuYXR0cihcImhlaWdodFwiLCBmdW5jdGlvbih2KSB7IHJldHVybiBnLm5vZGUodikuaGVpZ2h0OyB9KVxuICAgICAgLmF0dHIoXCJ4XCIsIGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgdmFyIG5vZGUgPSBnLm5vZGUodik7XG4gICAgICAgIHJldHVybiAtbm9kZS53aWR0aCAvIDI7XG4gICAgICB9KVxuICAgICAgLmF0dHIoXCJ5XCIsIGZ1bmN0aW9uKHYpIHtcbiAgICAgICAgdmFyIG5vZGUgPSBnLm5vZGUodik7XG4gICAgICAgIHJldHVybiAtbm9kZS5oZWlnaHQgLyAyO1xuICAgICAgfSk7XG5cbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgdXRpbCA9IHJlcXVpcmUoXCIuL3V0aWxcIiksXG4gICAgZDMgPSByZXF1aXJlKFwiLi9kM1wiKSxcbiAgICBfID0gcmVxdWlyZShcIi4vbG9kYXNoXCIpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHBvc2l0aW9uRWRnZUxhYmVscztcblxuZnVuY3Rpb24gcG9zaXRpb25FZGdlTGFiZWxzKHNlbGVjdGlvbiwgZykge1xuICB2YXIgY3JlYXRlZCA9IHNlbGVjdGlvbi5maWx0ZXIoZnVuY3Rpb24oKSB7IHJldHVybiAhZDMuc2VsZWN0KHRoaXMpLmNsYXNzZWQoXCJ1cGRhdGVcIik7IH0pO1xuXG4gIGZ1bmN0aW9uIHRyYW5zbGF0ZShlKSB7XG4gICAgdmFyIGVkZ2UgPSBnLmVkZ2UoZSk7XG4gICAgcmV0dXJuIF8uaGFzKGVkZ2UsIFwieFwiKSA/IFwidHJhbnNsYXRlKFwiICsgZWRnZS54ICsgXCIsXCIgKyBlZGdlLnkgKyBcIilcIiA6IFwiXCI7XG4gIH1cblxuICBjcmVhdGVkLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgdHJhbnNsYXRlKTtcblxuICB1dGlsLmFwcGx5VHJhbnNpdGlvbihzZWxlY3Rpb24sIGcpXG4gICAgLnN0eWxlKFwib3BhY2l0eVwiLCAxKVxuICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIHRyYW5zbGF0ZSk7XG59XG4iLCJcInVzZSBzdHJpY3RcIjtcblxudmFyIHV0aWwgPSByZXF1aXJlKFwiLi91dGlsXCIpLFxuICAgIGQzID0gcmVxdWlyZShcIi4vZDNcIik7XG5cbm1vZHVsZS5leHBvcnRzID0gcG9zaXRpb25Ob2RlcztcblxuZnVuY3Rpb24gcG9zaXRpb25Ob2RlcyhzZWxlY3Rpb24sIGcpIHtcbiAgdmFyIGNyZWF0ZWQgPSBzZWxlY3Rpb24uZmlsdGVyKGZ1bmN0aW9uKCkgeyByZXR1cm4gIWQzLnNlbGVjdCh0aGlzKS5jbGFzc2VkKFwidXBkYXRlXCIpOyB9KTtcblxuICBmdW5jdGlvbiB0cmFuc2xhdGUodikge1xuICAgIHZhciBub2RlID0gZy5ub2RlKHYpO1xuICAgIHJldHVybiBcInRyYW5zbGF0ZShcIiArIG5vZGUueCArIFwiLFwiICsgbm9kZS55ICsgXCIpXCI7XG4gIH1cblxuICBjcmVhdGVkLmF0dHIoXCJ0cmFuc2Zvcm1cIiwgdHJhbnNsYXRlKTtcblxuICB1dGlsLmFwcGx5VHJhbnNpdGlvbihzZWxlY3Rpb24sIGcpXG4gICAgLnN0eWxlKFwib3BhY2l0eVwiLCAxKVxuICAgIC5hdHRyKFwidHJhbnNmb3JtXCIsIHRyYW5zbGF0ZSk7XG59XG4iLCJ2YXIgXyA9IHJlcXVpcmUoXCIuL2xvZGFzaFwiKSxcbiAgICBsYXlvdXQgPSByZXF1aXJlKFwiLi9kYWdyZVwiKS5sYXlvdXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gcmVuZGVyO1xuXG4vLyBUaGlzIGRlc2lnbiBpcyBiYXNlZCBvbiBodHRwOi8vYm9zdC5vY2tzLm9yZy9taWtlL2NoYXJ0Ly5cbmZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgdmFyIGNyZWF0ZU5vZGVzID0gcmVxdWlyZShcIi4vY3JlYXRlLW5vZGVzXCIpLFxuICAgICAgY3JlYXRlQ2x1c3RlcnMgPSByZXF1aXJlKFwiLi9jcmVhdGUtY2x1c3RlcnNcIiksXG4gICAgICBjcmVhdGVFZGdlTGFiZWxzID0gcmVxdWlyZShcIi4vY3JlYXRlLWVkZ2UtbGFiZWxzXCIpLFxuICAgICAgY3JlYXRlRWRnZVBhdGhzID0gcmVxdWlyZShcIi4vY3JlYXRlLWVkZ2UtcGF0aHNcIiksXG4gICAgICBwb3NpdGlvbk5vZGVzID0gcmVxdWlyZShcIi4vcG9zaXRpb24tbm9kZXNcIiksXG4gICAgICBwb3NpdGlvbkVkZ2VMYWJlbHMgPSByZXF1aXJlKFwiLi9wb3NpdGlvbi1lZGdlLWxhYmVsc1wiKSxcbiAgICAgIHBvc2l0aW9uQ2x1c3RlcnMgPSByZXF1aXJlKFwiLi9wb3NpdGlvbi1jbHVzdGVyc1wiKSxcbiAgICAgIHNoYXBlcyA9IHJlcXVpcmUoXCIuL3NoYXBlc1wiKSxcbiAgICAgIGFycm93cyA9IHJlcXVpcmUoXCIuL2Fycm93c1wiKTtcblxuICB2YXIgZm4gPSBmdW5jdGlvbihzdmcsIGcpIHtcbiAgICBwcmVQcm9jZXNzR3JhcGgoZyk7XG5cbiAgICB2YXIgb3V0cHV0R3JvdXAgPSBjcmVhdGVPclNlbGVjdEdyb3VwKHN2ZywgXCJvdXRwdXRcIiksXG4gICAgICAgIGNsdXN0ZXJzR3JvdXAgPSBjcmVhdGVPclNlbGVjdEdyb3VwKG91dHB1dEdyb3VwLCBcImNsdXN0ZXJzXCIpLFxuICAgICAgICBlZGdlUGF0aHNHcm91cCA9IGNyZWF0ZU9yU2VsZWN0R3JvdXAob3V0cHV0R3JvdXAsIFwiZWRnZVBhdGhzXCIpLFxuICAgICAgICBlZGdlTGFiZWxzID0gY3JlYXRlRWRnZUxhYmVscyhjcmVhdGVPclNlbGVjdEdyb3VwKG91dHB1dEdyb3VwLCBcImVkZ2VMYWJlbHNcIiksIGcpLFxuICAgICAgICBub2RlcyA9IGNyZWF0ZU5vZGVzKGNyZWF0ZU9yU2VsZWN0R3JvdXAob3V0cHV0R3JvdXAsIFwibm9kZXNcIiksIGcsIHNoYXBlcyk7XG5cbiAgICBsYXlvdXQoZyk7XG5cbiAgICBwb3NpdGlvbk5vZGVzKG5vZGVzLCBnKTtcbiAgICBwb3NpdGlvbkVkZ2VMYWJlbHMoZWRnZUxhYmVscywgZyk7XG4gICAgY3JlYXRlRWRnZVBhdGhzKGVkZ2VQYXRoc0dyb3VwLCBnLCBhcnJvd3MpO1xuXG4gICAgdmFyIGNsdXN0ZXJzID0gY3JlYXRlQ2x1c3RlcnMoY2x1c3RlcnNHcm91cCwgZyk7XG4gICAgcG9zaXRpb25DbHVzdGVycyhjbHVzdGVycywgZyk7XG5cbiAgICBwb3N0UHJvY2Vzc0dyYXBoKGcpO1xuICB9O1xuXG4gIGZuLmNyZWF0ZU5vZGVzID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBjcmVhdGVOb2RlcztcbiAgICBjcmVhdGVOb2RlcyA9IHZhbHVlO1xuICAgIHJldHVybiBmbjtcbiAgfTtcblxuICBmbi5jcmVhdGVDbHVzdGVycyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY3JlYXRlQ2x1c3RlcnM7XG4gICAgY3JlYXRlQ2x1c3RlcnMgPSB2YWx1ZTtcbiAgICByZXR1cm4gZm47XG4gIH07XG5cbiAgZm4uY3JlYXRlRWRnZUxhYmVscyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY3JlYXRlRWRnZUxhYmVscztcbiAgICBjcmVhdGVFZGdlTGFiZWxzID0gdmFsdWU7XG4gICAgcmV0dXJuIGZuO1xuICB9O1xuXG4gIGZuLmNyZWF0ZUVkZ2VQYXRocyA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gY3JlYXRlRWRnZVBhdGhzO1xuICAgIGNyZWF0ZUVkZ2VQYXRocyA9IHZhbHVlO1xuICAgIHJldHVybiBmbjtcbiAgfTtcblxuICBmbi5zaGFwZXMgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNoYXBlcztcbiAgICBzaGFwZXMgPSB2YWx1ZTtcbiAgICByZXR1cm4gZm47XG4gIH07XG5cbiAgZm4uYXJyb3dzID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBhcnJvd3M7XG4gICAgYXJyb3dzID0gdmFsdWU7XG4gICAgcmV0dXJuIGZuO1xuICB9O1xuXG4gIHJldHVybiBmbjtcbn1cblxudmFyIE5PREVfREVGQVVMVF9BVFRSUyA9IHtcbiAgcGFkZGluZ0xlZnQ6IDEwLFxuICBwYWRkaW5nUmlnaHQ6IDEwLFxuICBwYWRkaW5nVG9wOiAxMCxcbiAgcGFkZGluZ0JvdHRvbTogMTAsXG4gIHJ4OiAwLFxuICByeTogMCxcbiAgc2hhcGU6IFwicmVjdFwiXG59O1xuXG52YXIgRURHRV9ERUZBVUxUX0FUVFJTID0ge1xuICBhcnJvd2hlYWQ6IFwibm9ybWFsXCIsXG4gIGxpbmVJbnRlcnBvbGF0ZTogXCJsaW5lYXJcIlxufTtcblxuZnVuY3Rpb24gcHJlUHJvY2Vzc0dyYXBoKGcpIHtcbiAgZy5ub2RlcygpLmZvckVhY2goZnVuY3Rpb24odikge1xuICAgIHZhciBub2RlID0gZy5ub2RlKHYpO1xuICAgIGlmICghXy5oYXMobm9kZSwgXCJsYWJlbFwiKSAmJiAhZy5jaGlsZHJlbih2KS5sZW5ndGgpIHsgbm9kZS5sYWJlbCA9IHY7IH1cblxuICAgIGlmIChfLmhhcyhub2RlLCBcInBhZGRpbmdYXCIpKSB7XG4gICAgICBfLmRlZmF1bHRzKG5vZGUsIHtcbiAgICAgICAgcGFkZGluZ0xlZnQ6IG5vZGUucGFkZGluZ1gsXG4gICAgICAgIHBhZGRpbmdSaWdodDogbm9kZS5wYWRkaW5nWFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKF8uaGFzKG5vZGUsIFwicGFkZGluZ1lcIikpIHtcbiAgICAgIF8uZGVmYXVsdHMobm9kZSwge1xuICAgICAgICBwYWRkaW5nVG9wOiBub2RlLnBhZGRpbmdZLFxuICAgICAgICBwYWRkaW5nQm90dG9tOiBub2RlLnBhZGRpbmdZXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoXy5oYXMobm9kZSwgXCJwYWRkaW5nXCIpKSB7XG4gICAgICBfLmRlZmF1bHRzKG5vZGUsIHtcbiAgICAgICAgcGFkZGluZ0xlZnQ6IG5vZGUucGFkZGluZyxcbiAgICAgICAgcGFkZGluZ1JpZ2h0OiBub2RlLnBhZGRpbmcsXG4gICAgICAgIHBhZGRpbmdUb3A6IG5vZGUucGFkZGluZyxcbiAgICAgICAgcGFkZGluZ0JvdHRvbTogbm9kZS5wYWRkaW5nXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBfLmRlZmF1bHRzKG5vZGUsIE5PREVfREVGQVVMVF9BVFRSUyk7XG5cbiAgICBfLmVhY2goW1wicGFkZGluZ0xlZnRcIiwgXCJwYWRkaW5nUmlnaHRcIiwgXCJwYWRkaW5nVG9wXCIsIFwicGFkZGluZ0JvdHRvbVwiXSwgZnVuY3Rpb24oaykge1xuICAgICAgbm9kZVtrXSA9IE51bWJlcihub2RlW2tdKTtcbiAgICB9KTtcblxuICAgIC8vIFNhdmUgZGltZW5zaW9ucyBmb3IgcmVzdG9yZSBkdXJpbmcgcG9zdC1wcm9jZXNzaW5nXG4gICAgaWYgKF8uaGFzKG5vZGUsIFwid2lkdGhcIikpIHsgbm9kZS5fcHJldldpZHRoID0gbm9kZS53aWR0aDsgfVxuICAgIGlmIChfLmhhcyhub2RlLCBcImhlaWdodFwiKSkgeyBub2RlLl9wcmV2SGVpZ2h0ID0gbm9kZS5oZWlnaHQ7IH1cbiAgfSk7XG5cbiAgZy5lZGdlcygpLmZvckVhY2goZnVuY3Rpb24oZSkge1xuICAgIHZhciBlZGdlID0gZy5lZGdlKGUpO1xuICAgIGlmICghXy5oYXMoZWRnZSwgXCJsYWJlbFwiKSkgeyBlZGdlLmxhYmVsID0gXCJcIjsgfVxuICAgIF8uZGVmYXVsdHMoZWRnZSwgRURHRV9ERUZBVUxUX0FUVFJTKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHBvc3RQcm9jZXNzR3JhcGgoZykge1xuICBfLmVhY2goZy5ub2RlcygpLCBmdW5jdGlvbih2KSB7XG4gICAgdmFyIG5vZGUgPSBnLm5vZGUodik7XG5cbiAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIGRpbWVuc2lvbnNcbiAgICBpZiAoXy5oYXMobm9kZSwgXCJfcHJldldpZHRoXCIpKSB7XG4gICAgICBub2RlLndpZHRoID0gbm9kZS5fcHJldldpZHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgbm9kZS53aWR0aDtcbiAgICB9XG5cbiAgICBpZiAoXy5oYXMobm9kZSwgXCJfcHJldkhlaWdodFwiKSkge1xuICAgICAgbm9kZS5oZWlnaHQgPSBub2RlLl9wcmV2SGVpZ2h0O1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgbm9kZS5oZWlnaHQ7XG4gICAgfVxuXG4gICAgZGVsZXRlIG5vZGUuX3ByZXZXaWR0aDtcbiAgICBkZWxldGUgbm9kZS5fcHJldkhlaWdodDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZU9yU2VsZWN0R3JvdXAocm9vdCwgbmFtZSkge1xuICB2YXIgc2VsZWN0aW9uID0gcm9vdC5zZWxlY3QoXCJnLlwiICsgbmFtZSk7XG4gIGlmIChzZWxlY3Rpb24uZW1wdHkoKSkge1xuICAgIHNlbGVjdGlvbiA9IHJvb3QuYXBwZW5kKFwiZ1wiKS5hdHRyKFwiY2xhc3NcIiwgbmFtZSk7XG4gIH1cbiAgcmV0dXJuIHNlbGVjdGlvbjtcbn1cbiIsIlwidXNlIHN0cmljdFwiO1xuXG52YXIgaW50ZXJzZWN0UmVjdCA9IHJlcXVpcmUoXCIuL2ludGVyc2VjdC9pbnRlcnNlY3QtcmVjdFwiKSxcbiAgICBpbnRlcnNlY3RFbGxpcHNlID0gcmVxdWlyZShcIi4vaW50ZXJzZWN0L2ludGVyc2VjdC1lbGxpcHNlXCIpLFxuICAgIGludGVyc2VjdENpcmNsZSA9IHJlcXVpcmUoXCIuL2ludGVyc2VjdC9pbnRlcnNlY3QtY2lyY2xlXCIpLFxuICAgIGludGVyc2VjdFBvbHlnb24gPSByZXF1aXJlKFwiLi9pbnRlcnNlY3QvaW50ZXJzZWN0LXBvbHlnb25cIik7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByZWN0OiByZWN0LFxuICBlbGxpcHNlOiBlbGxpcHNlLFxuICBjaXJjbGU6IGNpcmNsZSxcbiAgZGlhbW9uZDogZGlhbW9uZFxufTtcblxuZnVuY3Rpb24gcmVjdChwYXJlbnQsIGJib3gsIG5vZGUpIHtcbiAgdmFyIHNoYXBlU3ZnID0gcGFyZW50Lmluc2VydChcInJlY3RcIiwgXCI6Zmlyc3QtY2hpbGRcIilcbiAgICAgICAgLmF0dHIoXCJyeFwiLCBub2RlLnJ4KVxuICAgICAgICAuYXR0cihcInJ5XCIsIG5vZGUucnkpXG4gICAgICAgIC5hdHRyKFwieFwiLCAtYmJveC53aWR0aCAvIDIpXG4gICAgICAgIC5hdHRyKFwieVwiLCAtYmJveC5oZWlnaHQgLyAyKVxuICAgICAgICAuYXR0cihcIndpZHRoXCIsIGJib3gud2lkdGgpXG4gICAgICAgIC5hdHRyKFwiaGVpZ2h0XCIsIGJib3guaGVpZ2h0KTtcblxuICBub2RlLmludGVyc2VjdCA9IGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIGludGVyc2VjdFJlY3Qobm9kZSwgcG9pbnQpO1xuICB9O1xuXG4gIHJldHVybiBzaGFwZVN2Zztcbn1cblxuZnVuY3Rpb24gZWxsaXBzZShwYXJlbnQsIGJib3gsIG5vZGUpIHtcbiAgdmFyIHJ4ID0gYmJveC53aWR0aCAvIDIsXG4gICAgICByeSA9IGJib3guaGVpZ2h0IC8gMixcbiAgICAgIHNoYXBlU3ZnID0gcGFyZW50Lmluc2VydChcImVsbGlwc2VcIiwgXCI6Zmlyc3QtY2hpbGRcIilcbiAgICAgICAgLmF0dHIoXCJ4XCIsIC1iYm94LndpZHRoIC8gMilcbiAgICAgICAgLmF0dHIoXCJ5XCIsIC1iYm94LmhlaWdodCAvIDIpXG4gICAgICAgIC5hdHRyKFwicnhcIiwgcngpXG4gICAgICAgIC5hdHRyKFwicnlcIiwgcnkpO1xuXG4gIG5vZGUuaW50ZXJzZWN0ID0gZnVuY3Rpb24ocG9pbnQpIHtcbiAgICByZXR1cm4gaW50ZXJzZWN0RWxsaXBzZShub2RlLCByeCwgcnksIHBvaW50KTtcbiAgfTtcblxuICByZXR1cm4gc2hhcGVTdmc7XG59XG5cbmZ1bmN0aW9uIGNpcmNsZShwYXJlbnQsIGJib3gsIG5vZGUpIHtcbiAgdmFyIHIgPSBNYXRoLm1heChiYm94LndpZHRoLCBiYm94LmhlaWdodCkgLyAyLFxuICAgICAgc2hhcGVTdmcgPSBwYXJlbnQuaW5zZXJ0KFwiY2lyY2xlXCIsIFwiOmZpcnN0LWNoaWxkXCIpXG4gICAgICAgIC5hdHRyKFwieFwiLCAtYmJveC53aWR0aCAvIDIpXG4gICAgICAgIC5hdHRyKFwieVwiLCAtYmJveC5oZWlnaHQgLyAyKVxuICAgICAgICAuYXR0cihcInJcIiwgcik7XG5cbiAgbm9kZS5pbnRlcnNlY3QgPSBmdW5jdGlvbihwb2ludCkge1xuICAgIHJldHVybiBpbnRlcnNlY3RDaXJjbGUobm9kZSwgciwgcG9pbnQpO1xuICB9O1xuXG4gIHJldHVybiBzaGFwZVN2Zztcbn1cblxuLy8gQ2lyY3Vtc2NyaWJlIGFuIGVsbGlwc2UgZm9yIHRoZSBib3VuZGluZyBib3ggd2l0aCBhIGRpYW1vbmQgc2hhcGUuIEkgZGVyaXZlZFxuLy8gdGhlIGZ1bmN0aW9uIHRvIGNhbGN1bGF0ZSB0aGUgZGlhbW9uZCBzaGFwZSBmcm9tOlxuLy8gaHR0cDovL21hdGhmb3J1bS5vcmcva2IvbWVzc2FnZS5qc3BhP21lc3NhZ2VJRD0zNzUwMjM2XG5mdW5jdGlvbiBkaWFtb25kKHBhcmVudCwgYmJveCwgbm9kZSkge1xuICB2YXIgdyA9IChiYm94LndpZHRoICogTWF0aC5TUVJUMikgLyAyLFxuICAgICAgaCA9IChiYm94LmhlaWdodCAqIE1hdGguU1FSVDIpIC8gMixcbiAgICAgIHBvaW50cyA9IFtcbiAgICAgICAgeyB4OiAgMCwgeTogLWggfSxcbiAgICAgICAgeyB4OiAtdywgeTogIDAgfSxcbiAgICAgICAgeyB4OiAgMCwgeTogIGggfSxcbiAgICAgICAgeyB4OiAgdywgeTogIDAgfVxuICAgICAgXSxcbiAgICAgIHNoYXBlU3ZnID0gcGFyZW50Lmluc2VydChcInBvbHlnb25cIiwgXCI6Zmlyc3QtY2hpbGRcIilcbiAgICAgICAgLmF0dHIoXCJwb2ludHNcIiwgcG9pbnRzLm1hcChmdW5jdGlvbihwKSB7IHJldHVybiBwLnggKyBcIixcIiArIHAueTsgfSkuam9pbihcIiBcIikpO1xuXG4gIG5vZGUuaW50ZXJzZWN0ID0gZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiBpbnRlcnNlY3RQb2x5Z29uKG5vZGUsIHBvaW50cywgcCk7XG4gIH07XG5cbiAgcmV0dXJuIHNoYXBlU3ZnO1xufVxuIiwidmFyIF8gPSByZXF1aXJlKFwiLi9sb2Rhc2hcIik7XG5cbi8vIFB1YmxpYyB1dGlsaXR5IGZ1bmN0aW9uc1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGlzU3ViZ3JhcGg6IGlzU3ViZ3JhcGgsXG4gIGVkZ2VUb0lkOiBlZGdlVG9JZCxcbiAgYXBwbHlTdHlsZTogYXBwbHlTdHlsZSxcbiAgYXBwbHlDbGFzczogYXBwbHlDbGFzcyxcbiAgYXBwbHlUcmFuc2l0aW9uOiBhcHBseVRyYW5zaXRpb25cbn07XG5cbi8qXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBub2RlIGluIHRoZSBncmFwaCBpcyBhIHN1YmdyYXBoIG5vZGUuIEFcbiAqIHN1YmdyYXBoIG5vZGUgaXMgb25lIHRoYXQgY29udGFpbnMgb3RoZXIgbm9kZXMuXG4gKi9cbmZ1bmN0aW9uIGlzU3ViZ3JhcGgoZywgdikge1xuICByZXR1cm4gISFnLmNoaWxkcmVuKHYpLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gZWRnZVRvSWQoZSkge1xuICByZXR1cm4gZXNjYXBlSWQoZS52KSArIFwiOlwiICsgZXNjYXBlSWQoZS53KSArIFwiOlwiICsgZXNjYXBlSWQoZS5uYW1lKTtcbn1cblxudmFyIElEX0RFTElNID0gLzovZztcbmZ1bmN0aW9uIGVzY2FwZUlkKHN0cikge1xuICByZXR1cm4gc3RyID8gU3RyaW5nKHN0cikucmVwbGFjZShJRF9ERUxJTSwgXCJcXFxcOlwiKSA6IFwiXCI7XG59XG5cbmZ1bmN0aW9uIGFwcGx5U3R5bGUoZG9tLCBzdHlsZUZuKSB7XG4gIGlmIChzdHlsZUZuKSB7XG4gICAgZG9tLmF0dHIoXCJzdHlsZVwiLCBzdHlsZUZuKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBseUNsYXNzKGRvbSwgY2xhc3NGbiwgb3RoZXJDbGFzc2VzKSB7XG4gIGlmIChjbGFzc0ZuKSB7XG4gICAgZG9tXG4gICAgICAuYXR0cihcImNsYXNzXCIsIGNsYXNzRm4pXG4gICAgICAuYXR0cihcImNsYXNzXCIsIG90aGVyQ2xhc3NlcyArIFwiIFwiICsgZG9tLmF0dHIoXCJjbGFzc1wiKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXBwbHlUcmFuc2l0aW9uKHNlbGVjdGlvbiwgZykge1xuICB2YXIgZ3JhcGggPSBnLmdyYXBoKCk7XG5cbiAgaWYgKF8uaXNQbGFpbk9iamVjdChncmFwaCkpIHtcbiAgICB2YXIgdHJhbnNpdGlvbiA9IGdyYXBoLnRyYW5zaXRpb247XG4gICAgaWYgKF8uaXNGdW5jdGlvbih0cmFuc2l0aW9uKSkge1xuICAgICAgcmV0dXJuIHRyYW5zaXRpb24oc2VsZWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc2VsZWN0aW9uO1xufVxuIiwibW9kdWxlLmV4cG9ydHMgPSBcIjAuNC4xN1wiO1xuIl19\n","var util = require(\"./util\");\n\nmodule.exports = {\n  \"default\": normal,\n  \"normal\": normal,\n  \"vee\": vee,\n  \"undirected\": undirected\n};\n\nfunction normal(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 0 L 10 5 L 0 10 z\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n\nfunction vee(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 0 L 10 5 L 0 10 L 4 5 z\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n\nfunction undirected(parent, id, edge, type) {\n  var marker = parent.append(\"marker\")\n    .attr(\"id\", id)\n    .attr(\"viewBox\", \"0 0 10 10\")\n    .attr(\"refX\", 9)\n    .attr(\"refY\", 5)\n    .attr(\"markerUnits\", \"strokeWidth\")\n    .attr(\"markerWidth\", 8)\n    .attr(\"markerHeight\", 6)\n    .attr(\"orient\", \"auto\");\n\n  var path = marker.append(\"path\")\n    .attr(\"d\", \"M 0 5 L 10 5\")\n    .style(\"stroke-width\", 1)\n    .style(\"stroke-dasharray\", \"1,0\");\n  util.applyStyle(path, edge[type + \"Style\"]);\n  if (edge[type + \"Class\"]) {\n    path.attr(\"class\", edge[type + \"Class\"]);\n  }\n}\n","var util = require(\"./util\"),\n    addLabel = require(\"./label/add-label\");\n\nmodule.exports = createClusters;\n\nfunction createClusters(selection, g) {\n  var clusters = g.nodes().filter(function(v) { return util.isSubgraph(g, v); }),\n      svgClusters = selection.selectAll(\"g.cluster\")\n        .data(clusters, function(v) { return v; });\n\n  svgClusters.selectAll(\"*\").remove();\n  svgClusters.enter()\n    .append(\"g\")\n      .attr(\"class\", \"cluster\")\n      .attr(\"id\",function(v){\n          var node = g.node(v);\n          return node.id;\n      })\n      .style(\"opacity\", 0);\n\n  util.applyTransition(svgClusters, g)\n    .style(\"opacity\", 1);\n\n  svgClusters.each(function(v) {\n    var node = g.node(v),\n        thisGroup = d3.select(this);\n    d3.select(this).append(\"rect\");\n    var labelGroup = thisGroup.append(\"g\").attr(\"class\", \"label\");\n    addLabel(labelGroup, node, node.clusterLabelPos);\n  });\n\n  svgClusters.selectAll(\"rect\").each(function(c) {\n    var node = g.node(c);\n    var domCluster = d3.select(this);\n    util.applyStyle(domCluster, node.style);\n  });\n\n  util.applyTransition(svgClusters.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgClusters;\n}\n","\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    addLabel = require(\"./label/add-label\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = createEdgeLabels;\n\nfunction createEdgeLabels(selection, g) {\n  var svgEdgeLabels = selection.selectAll(\"g.edgeLabel\")\n    .data(g.edges(), function(e) { return util.edgeToId(e); })\n    .classed(\"update\", true);\n\n  svgEdgeLabels.selectAll(\"*\").remove();\n  svgEdgeLabels.enter()\n    .append(\"g\")\n      .classed(\"edgeLabel\", true)\n      .style(\"opacity\", 0);\n  svgEdgeLabels.each(function(e) {\n    var edge = g.edge(e),\n        label = addLabel(d3.select(this), g.edge(e), 0, 0).classed(\"label\", true),\n        bbox = label.node().getBBox();\n\n    if (edge.labelId) { label.attr(\"id\", edge.labelId); }\n    if (!_.has(edge, \"width\")) { edge.width = bbox.width; }\n    if (!_.has(edge, \"height\")) { edge.height = bbox.height; }\n  });\n\n  util.applyTransition(svgEdgeLabels.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgEdgeLabels;\n}\n","\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    intersectNode = require(\"./intersect/intersect-node\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\nmodule.exports = createEdgePaths;\n\nfunction createEdgePaths(selection, g, arrows) {\n  var svgPaths = selection.selectAll(\"g.edgePath\")\n    .data(g.edges(), function(e) { return util.edgeToId(e); })\n    .classed(\"update\", true);\n\n  enter(svgPaths, g);\n  exit(svgPaths, g);\n\n  util.applyTransition(svgPaths, g)\n    .style(\"opacity\", 1);\n\n  // Save DOM element in the path group, and set ID and class\n  svgPaths.each(function(e) {\n    var domEdge = d3.select(this);\n    var edge = g.edge(e);\n    edge.elem = this;\n\n    if (edge.id) {\n      domEdge.attr(\"id\", edge.id);\n    }\n\n    util.applyClass(domEdge, edge[\"class\"],\n      (domEdge.classed(\"update\") ? \"update \" : \"\") + \"edgePath\");\n  });\n\n  svgPaths.selectAll(\"path.path\")\n    .each(function(e) {\n      var edge = g.edge(e);\n      edge.arrowheadId = _.uniqueId(\"arrowhead\");\n\n      var domEdge = d3.select(this)\n        .attr(\"marker-end\", function() {\n            return \"url(\" + makeFragmentRef(location.href, edge.arrowheadId) + \")\";\n        })\n        .style(\"fill\", \"none\");\n\n      util.applyTransition(domEdge, g)\n        .attr(\"d\", function(e) { return calcPoints(g, e); });\n\n      util.applyStyle(domEdge, edge.style);\n    });\n\n  svgPaths.selectAll(\"defs *\").remove();\n  svgPaths.selectAll(\"defs\")\n    .each(function(e) {\n      var edge = g.edge(e),\n          arrowhead = arrows[edge.arrowhead];\n      arrowhead(d3.select(this), edge.arrowheadId, edge, \"arrowhead\");\n    });\n\n  return svgPaths;\n}\n\nfunction makeFragmentRef(url, fragmentId) {\n  var baseUrl = url.split(\"#\")[0];\n  return baseUrl + \"#\" + fragmentId;\n}\n\nfunction calcPoints(g, e) {\n  var edge = g.edge(e),\n      tail = g.node(e.v),\n      head = g.node(e.w),\n      points = edge.points.slice(1, edge.points.length - 1);\n  points.unshift(intersectNode(tail, points[0]));\n  points.push(intersectNode(head, points[points.length - 1]));\n\n  return createLine(edge, points);\n}\n\nfunction createLine(edge, points) {\n  var line = d3.svg.line()\n    .x(function(d) { return d.x; })\n    .y(function(d) { return d.y; });\n\n  if (_.has(edge, \"lineInterpolate\")) {\n    line.interpolate(edge.lineInterpolate);\n  }\n\n  if (_.has(edge, \"lineTension\")) {\n    line.tension(Number(edge.lineTension));\n  }\n\n  return line(points);\n}\n\nfunction getCoords(elem) {\n  var bbox = elem.getBBox(),\n      matrix = elem.ownerSVGElement.getScreenCTM()\n        .inverse()\n        .multiply(elem.getScreenCTM())\n        .translate(bbox.width / 2, bbox.height / 2);\n  return { x: matrix.e, y: matrix.f };\n}\n\nfunction enter(svgPaths, g) {\n  var svgPathsEnter = svgPaths.enter()\n    .append(\"g\")\n      .attr(\"class\", \"edgePath\")\n      .style(\"opacity\", 0);\n  svgPathsEnter.append(\"path\")\n    .attr(\"class\", \"path\")\n    .attr(\"d\", function(e) {\n      var edge = g.edge(e),\n          sourceElem = g.node(e.v).elem,\n          points = _.range(edge.points.length).map(function() { return getCoords(sourceElem); });\n      return createLine(edge, points);\n    });\n  svgPathsEnter.append(\"defs\");\n}\n\nfunction exit(svgPaths, g) {\n  var svgPathExit = svgPaths.exit();\n  util.applyTransition(svgPathExit, g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  util.applyTransition(svgPathExit.select(\"path.path\"), g)\n    .attr(\"d\", function(e) {\n      var source = g.node(e.v);\n\n      if (source) {\n        var points = _.range(this.getTotalLength()).map(function() { return source; });\n        return createLine({}, points);\n      } else {\n        return d3.select(this).attr(\"d\");\n      }\n    });\n}\n","\"use strict\";\n\nvar _ = require(\"./lodash\"),\n    addLabel = require(\"./label/add-label\"),\n    util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = createNodes;\n\nfunction createNodes(selection, g, shapes) {\n  var simpleNodes = g.nodes().filter(function(v) { return !util.isSubgraph(g, v); });\n  var svgNodes = selection.selectAll(\"g.node\")\n    .data(simpleNodes, function(v) { return v; })\n    .classed(\"update\", true);\n\n  svgNodes.selectAll(\"*\").remove();\n  svgNodes.enter()\n    .append(\"g\")\n      .attr(\"class\", \"node\")\n      .style(\"opacity\", 0);\n  svgNodes.each(function(v) {\n    var node = g.node(v),\n        thisGroup = d3.select(this),\n        labelGroup = thisGroup.append(\"g\").attr(\"class\", \"label\"),\n        labelDom = addLabel(labelGroup, node),\n        shape = shapes[node.shape],\n        bbox = _.pick(labelDom.node().getBBox(), \"width\", \"height\");\n\n    node.elem = this;\n\n    if (node.id) { thisGroup.attr(\"id\", node.id); }\n    if (node.labelId) { labelGroup.attr(\"id\", node.labelId); }\n    util.applyClass(thisGroup, node[\"class\"],\n      (thisGroup.classed(\"update\") ? \"update \" : \"\") + \"node\");\n\n    if (_.has(node, \"width\")) { bbox.width = node.width; }\n    if (_.has(node, \"height\")) { bbox.height = node.height; }\n\n    bbox.width += node.paddingLeft + node.paddingRight;\n    bbox.height += node.paddingTop + node.paddingBottom;\n    labelGroup.attr(\"transform\", \"translate(\" +\n      ((node.paddingLeft - node.paddingRight) / 2) + \",\" +\n      ((node.paddingTop - node.paddingBottom) / 2) + \")\");\n\n    var shapeSvg = shape(d3.select(this), bbox, node);\n    util.applyStyle(shapeSvg, node.style);\n\n    var shapeBBox = shapeSvg.node().getBBox();\n    node.width = shapeBBox.width;\n    node.height = shapeBBox.height;\n  });\n\n  util.applyTransition(svgNodes.exit(), g)\n    .style(\"opacity\", 0)\n    .remove();\n\n  return svgNodes;\n}\n","// Stub to get D3 either via NPM or from the global object\nmodule.exports = window.d3;\n","/* global window */\n\nvar dagre;\n\nif (require) {\n  try {\n    dagre = require(\"dagre\");\n  } catch (e) {}\n}\n\nif (!dagre) {\n  dagre = window.dagre;\n}\n\nmodule.exports = dagre;\n","/* global window */\n\nvar graphlib;\n\nif (require) {\n  try {\n    graphlib = require(\"graphlib\");\n  } catch (e) {}\n}\n\nif (!graphlib) {\n  graphlib = window.graphlib;\n}\n\nmodule.exports = graphlib;\n","module.exports = {\n  node: require(\"./intersect-node\"),\n  circle: require(\"./intersect-circle\"),\n  ellipse: require(\"./intersect-ellipse\"),\n  polygon: require(\"./intersect-polygon\"),\n  rect: require(\"./intersect-rect\")\n};\n","var intersectEllipse = require(\"./intersect-ellipse\");\n\nmodule.exports = intersectCircle;\n\nfunction intersectCircle(node, rx, point) {\n  return intersectEllipse(node, rx, rx, point);\n}\n","module.exports = intersectEllipse;\n\nfunction intersectEllipse(node, rx, ry, point) {\n  // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html\n\n  var cx = node.x;\n  var cy = node.y;\n\n  var px = cx - point.x;\n  var py = cy - point.y;\n\n  var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);\n\n  var dx = Math.abs(rx * ry * px / det);\n  if (point.x < cx) {\n    dx = -dx;\n  }\n  var dy = Math.abs(rx * ry * py / det);\n  if (point.y < cy) {\n    dy = -dy;\n  }\n\n  return {x: cx + dx, y: cy + dy};\n}\n\n","module.exports = intersectLine;\n\n/*\n * Returns the point at which two lines, p and q, intersect or returns\n * undefined if they do not intersect.\n */\nfunction intersectLine(p1, p2, q1, q2) {\n  // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994,\n  // p7 and p473.\n\n  var a1, a2, b1, b2, c1, c2;\n  var r1, r2 , r3, r4;\n  var denom, offset, num;\n  var x, y;\n\n  // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x +\n  // b1 y + c1 = 0.\n  a1 = p2.y - p1.y;\n  b1 = p1.x - p2.x;\n  c1 = (p2.x * p1.y) - (p1.x * p2.y);\n\n  // Compute r3 and r4.\n  r3 = ((a1 * q1.x) + (b1 * q1.y) + c1);\n  r4 = ((a1 * q2.x) + (b1 * q2.y) + c1);\n\n  // Check signs of r3 and r4. If both point 3 and point 4 lie on\n  // same side of line 1, the line segments do not intersect.\n  if ((r3 !== 0) && (r4 !== 0) && sameSign(r3, r4)) {\n    return /*DONT_INTERSECT*/;\n  }\n\n  // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0\n  a2 = q2.y - q1.y;\n  b2 = q1.x - q2.x;\n  c2 = (q2.x * q1.y) - (q1.x * q2.y);\n\n  // Compute r1 and r2\n  r1 = (a2 * p1.x) + (b2 * p1.y) + c2;\n  r2 = (a2 * p2.x) + (b2 * p2.y) + c2;\n\n  // Check signs of r1 and r2. If both point 1 and point 2 lie\n  // on same side of second line segment, the line segments do\n  // not intersect.\n  if ((r1 !== 0) && (r2 !== 0) && (sameSign(r1, r2))) {\n    return /*DONT_INTERSECT*/;\n  }\n\n  // Line segments intersect: compute intersection point.\n  denom = (a1 * b2) - (a2 * b1);\n  if (denom === 0) {\n    return /*COLLINEAR*/;\n  }\n\n  offset = Math.abs(denom / 2);\n\n  // The denom/2 is to get rounding instead of truncating. It\n  // is added or subtracted to the numerator, depending upon the\n  // sign of the numerator.\n  num = (b1 * c2) - (b2 * c1);\n  x = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);\n\n  num = (a2 * c1) - (a1 * c2);\n  y = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);\n\n  return { x: x, y: y };\n}\n\nfunction sameSign(r1, r2) {\n  return r1 * r2 > 0;\n}\n","module.exports = intersectNode;\n\nfunction intersectNode(node, point) {\n  return node.intersect(point);\n}\n","var intersectLine = require(\"./intersect-line\");\n\nmodule.exports = intersectPolygon;\n\n/*\n * Returns the point ({x, y}) at which the point argument intersects with the\n * node argument assuming that it has the shape specified by polygon.\n */\nfunction intersectPolygon(node, polyPoints, point) {\n  var x1 = node.x;\n  var y1 = node.y;\n\n  var intersections = [];\n\n  var minX = Number.POSITIVE_INFINITY,\n      minY = Number.POSITIVE_INFINITY;\n  polyPoints.forEach(function(entry) {\n    minX = Math.min(minX, entry.x);\n    minY = Math.min(minY, entry.y);\n  });\n\n  var left = x1 - node.width / 2 - minX;\n  var top =  y1 - node.height / 2 - minY;\n\n  for (var i = 0; i < polyPoints.length; i++) {\n    var p1 = polyPoints[i];\n    var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];\n    var intersect = intersectLine(node, point,\n      {x: left + p1.x, y: top + p1.y}, {x: left + p2.x, y: top + p2.y});\n    if (intersect) {\n      intersections.push(intersect);\n    }\n  }\n\n  if (!intersections.length) {\n    console.log(\"NO INTERSECTION FOUND, RETURN NODE CENTER\", node);\n    return node;\n  }\n\n  if (intersections.length > 1) {\n    // More intersections, find the one nearest to edge end point\n    intersections.sort(function(p, q) {\n      var pdx = p.x - point.x,\n          pdy = p.y - point.y,\n          distp = Math.sqrt(pdx * pdx + pdy * pdy),\n\n          qdx = q.x - point.x,\n          qdy = q.y - point.y,\n          distq = Math.sqrt(qdx * qdx + qdy * qdy);\n\n      return (distp < distq) ? -1 : (distp === distq ? 0 : 1);\n    });\n  }\n  return intersections[0];\n}\n","module.exports = intersectRect;\n\nfunction intersectRect(node, point) {\n  var x = node.x;\n  var y = node.y;\n\n  // Rectangle intersection algorithm from:\n  // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes\n  var dx = point.x - x;\n  var dy = point.y - y;\n  var w = node.width / 2;\n  var h = node.height / 2;\n\n  var sx, sy;\n  if (Math.abs(dy) * w > Math.abs(dx) * h) {\n    // Intersection is top or bottom of rect.\n    if (dy < 0) {\n      h = -h;\n    }\n    sx = dy === 0 ? 0 : h * dx / dy;\n    sy = h;\n  } else {\n    // Intersection is left or right of rect.\n    if (dx < 0) {\n      w = -w;\n    }\n    sx = w;\n    sy = dx === 0 ? 0 : w * dy / dx;\n  }\n\n  return {x: x + sx, y: y + sy};\n}\n","var util = require(\"../util\");\n\nmodule.exports = addHtmlLabel;\n\nfunction addHtmlLabel(root, node) {\n  var fo = root\n    .append(\"foreignObject\")\n      .attr(\"width\", \"100000\");\n\n  var div = fo\n    .append(\"xhtml:div\");\n  div.attr(\"xmlns\", \"http://www.w3.org/1999/xhtml\");\n\n  var label = node.label;\n  switch(typeof label) {\n    case \"function\":\n      div.insert(label);\n      break;\n    case \"object\":\n      // Currently we assume this is a DOM object.\n      div.insert(function() { return label; });\n      break;\n    default: div.html(label);\n  }\n\n  util.applyStyle(div, node.labelStyle);\n  div.style(\"display\", \"inline-block\");\n  // Fix for firefox\n  div.style(\"white-space\", \"nowrap\");\n\n  var client = div[0][0].getBoundingClientRect();\n  fo\n    .attr(\"width\", client.width)\n    .attr(\"height\", client.height); \n\n  return fo;\n}\n","var addTextLabel = require(\"./add-text-label\"),\n    addHtmlLabel = require(\"./add-html-label\"),\n    addSVGLabel  = require(\"./add-svg-label\");\n\nmodule.exports = addLabel;\n\nfunction addLabel(root, node, location) {\n  var label = node.label;\n  var labelSvg = root.append(\"g\");\n\n  // Allow the label to be a string, a function that returns a DOM element, or\n  // a DOM element itself.\n  if (node.labelType === \"svg\") {\n    addSVGLabel(labelSvg, node);\n  } else if (typeof label !== \"string\" || node.labelType === \"html\") {\n    addHtmlLabel(labelSvg, node);\n  } else {\n    addTextLabel(labelSvg, node);\n  }\n\n  var labelBBox = labelSvg.node().getBBox();\n  var y;\n  switch(location) {\n    case \"top\":\n      y = (-node.height / 2);\n      break;\n    case \"bottom\":\n      y = (node.height / 2) - labelBBox.height;\n      break;\n    default:\n      y = (-labelBBox.height / 2);\n  }\n  labelSvg.attr(\"transform\",\n                \"translate(\" + (-labelBBox.width / 2) + \",\" + y + \")\");\n\n  return labelSvg;\n}\n","var util = require(\"../util\");\n\nmodule.exports = addSVGLabel;\n\nfunction addSVGLabel(root, node) {\n  var domNode = root;\n\n  domNode.node().appendChild(node.label);\n\n  util.applyStyle(domNode, node.labelStyle);\n\n  return domNode;\n}\n","var util = require(\"../util\");\n\nmodule.exports = addTextLabel;\n\n/*\n * Attaches a text label to the specified root. Handles escape sequences.\n */\nfunction addTextLabel(root, node) {\n  var domNode = root.append(\"text\");\n\n  var lines = processEscapeSequences(node.label).split(\"\\n\");\n  for (var i = 0; i < lines.length; i++) {\n    domNode\n      .append(\"tspan\")\n        .attr(\"xml:space\", \"preserve\")\n        .attr(\"dy\", \"1em\")\n        .attr(\"x\", \"1\")\n        .text(lines[i]);\n  }\n\n  util.applyStyle(domNode, node.labelStyle);\n\n  return domNode;\n}\n\nfunction processEscapeSequences(text) {\n  var newText = \"\",\n      escaped = false,\n      ch;\n  for (var i = 0; i < text.length; ++i) {\n    ch = text[i];\n    if (escaped) {\n      switch(ch) {\n        case \"n\": newText += \"\\n\"; break;\n        default: newText += ch;\n      }\n      escaped = false;\n    } else if (ch === \"\\\\\") {\n      escaped = true;\n    } else {\n      newText += ch;\n    }\n  }\n  return newText;\n}\n","/* global window */\n\nvar lodash;\n\nif (require) {\n  try {\n    lodash = require(\"lodash\");\n  } catch (e) {}\n}\n\nif (!lodash) {\n  lodash = window._;\n}\n\nmodule.exports = lodash;\n","\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = positionClusters;\n\nfunction positionClusters(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(v) {\n    var node = g.node(v);\n    return \"translate(\" + node.x + \",\" + node.y + \")\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n      .style(\"opacity\", 1)\n      .attr(\"transform\", translate);\n\n  util.applyTransition(created.selectAll(\"rect\"), g)\n      .attr(\"width\", function(v) { return g.node(v).width; })\n      .attr(\"height\", function(v) { return g.node(v).height; })\n      .attr(\"x\", function(v) {\n        var node = g.node(v);\n        return -node.width / 2;\n      })\n      .attr(\"y\", function(v) {\n        var node = g.node(v);\n        return -node.height / 2;\n      });\n\n}\n","\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\"),\n    _ = require(\"./lodash\");\n\nmodule.exports = positionEdgeLabels;\n\nfunction positionEdgeLabels(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(e) {\n    var edge = g.edge(e);\n    return _.has(edge, \"x\") ? \"translate(\" + edge.x + \",\" + edge.y + \")\" : \"\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n    .style(\"opacity\", 1)\n    .attr(\"transform\", translate);\n}\n","\"use strict\";\n\nvar util = require(\"./util\"),\n    d3 = require(\"./d3\");\n\nmodule.exports = positionNodes;\n\nfunction positionNodes(selection, g) {\n  var created = selection.filter(function() { return !d3.select(this).classed(\"update\"); });\n\n  function translate(v) {\n    var node = g.node(v);\n    return \"translate(\" + node.x + \",\" + node.y + \")\";\n  }\n\n  created.attr(\"transform\", translate);\n\n  util.applyTransition(selection, g)\n    .style(\"opacity\", 1)\n    .attr(\"transform\", translate);\n}\n","var _ = require(\"./lodash\"),\n    layout = require(\"./dagre\").layout;\n\nmodule.exports = render;\n\n// This design is based on http://bost.ocks.org/mike/chart/.\nfunction render() {\n  var createNodes = require(\"./create-nodes\"),\n      createClusters = require(\"./create-clusters\"),\n      createEdgeLabels = require(\"./create-edge-labels\"),\n      createEdgePaths = require(\"./create-edge-paths\"),\n      positionNodes = require(\"./position-nodes\"),\n      positionEdgeLabels = require(\"./position-edge-labels\"),\n      positionClusters = require(\"./position-clusters\"),\n      shapes = require(\"./shapes\"),\n      arrows = require(\"./arrows\");\n\n  var fn = function(svg, g) {\n    preProcessGraph(g);\n\n    var outputGroup = createOrSelectGroup(svg, \"output\"),\n        clustersGroup = createOrSelectGroup(outputGroup, \"clusters\"),\n        edgePathsGroup = createOrSelectGroup(outputGroup, \"edgePaths\"),\n        edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, \"edgeLabels\"), g),\n        nodes = createNodes(createOrSelectGroup(outputGroup, \"nodes\"), g, shapes);\n\n    layout(g);\n\n    positionNodes(nodes, g);\n    positionEdgeLabels(edgeLabels, g);\n    createEdgePaths(edgePathsGroup, g, arrows);\n\n    var clusters = createClusters(clustersGroup, g);\n    positionClusters(clusters, g);\n\n    postProcessGraph(g);\n  };\n\n  fn.createNodes = function(value) {\n    if (!arguments.length) return createNodes;\n    createNodes = value;\n    return fn;\n  };\n\n  fn.createClusters = function(value) {\n    if (!arguments.length) return createClusters;\n    createClusters = value;\n    return fn;\n  };\n\n  fn.createEdgeLabels = function(value) {\n    if (!arguments.length) return createEdgeLabels;\n    createEdgeLabels = value;\n    return fn;\n  };\n\n  fn.createEdgePaths = function(value) {\n    if (!arguments.length) return createEdgePaths;\n    createEdgePaths = value;\n    return fn;\n  };\n\n  fn.shapes = function(value) {\n    if (!arguments.length) return shapes;\n    shapes = value;\n    return fn;\n  };\n\n  fn.arrows = function(value) {\n    if (!arguments.length) return arrows;\n    arrows = value;\n    return fn;\n  };\n\n  return fn;\n}\n\nvar NODE_DEFAULT_ATTRS = {\n  paddingLeft: 10,\n  paddingRight: 10,\n  paddingTop: 10,\n  paddingBottom: 10,\n  rx: 0,\n  ry: 0,\n  shape: \"rect\"\n};\n\nvar EDGE_DEFAULT_ATTRS = {\n  arrowhead: \"normal\",\n  lineInterpolate: \"linear\"\n};\n\nfunction preProcessGraph(g) {\n  g.nodes().forEach(function(v) {\n    var node = g.node(v);\n    if (!_.has(node, \"label\") && !g.children(v).length) { node.label = v; }\n\n    if (_.has(node, \"paddingX\")) {\n      _.defaults(node, {\n        paddingLeft: node.paddingX,\n        paddingRight: node.paddingX\n      });\n    }\n\n    if (_.has(node, \"paddingY\")) {\n      _.defaults(node, {\n        paddingTop: node.paddingY,\n        paddingBottom: node.paddingY\n      });\n    }\n\n    if (_.has(node, \"padding\")) {\n      _.defaults(node, {\n        paddingLeft: node.padding,\n        paddingRight: node.padding,\n        paddingTop: node.padding,\n        paddingBottom: node.padding\n      });\n    }\n\n    _.defaults(node, NODE_DEFAULT_ATTRS);\n\n    _.each([\"paddingLeft\", \"paddingRight\", \"paddingTop\", \"paddingBottom\"], function(k) {\n      node[k] = Number(node[k]);\n    });\n\n    // Save dimensions for restore during post-processing\n    if (_.has(node, \"width\")) { node._prevWidth = node.width; }\n    if (_.has(node, \"height\")) { node._prevHeight = node.height; }\n  });\n\n  g.edges().forEach(function(e) {\n    var edge = g.edge(e);\n    if (!_.has(edge, \"label\")) { edge.label = \"\"; }\n    _.defaults(edge, EDGE_DEFAULT_ATTRS);\n  });\n}\n\nfunction postProcessGraph(g) {\n  _.each(g.nodes(), function(v) {\n    var node = g.node(v);\n\n    // Restore original dimensions\n    if (_.has(node, \"_prevWidth\")) {\n      node.width = node._prevWidth;\n    } else {\n      delete node.width;\n    }\n\n    if (_.has(node, \"_prevHeight\")) {\n      node.height = node._prevHeight;\n    } else {\n      delete node.height;\n    }\n\n    delete node._prevWidth;\n    delete node._prevHeight;\n  });\n}\n\nfunction createOrSelectGroup(root, name) {\n  var selection = root.select(\"g.\" + name);\n  if (selection.empty()) {\n    selection = root.append(\"g\").attr(\"class\", name);\n  }\n  return selection;\n}\n","\"use strict\";\n\nvar intersectRect = require(\"./intersect/intersect-rect\"),\n    intersectEllipse = require(\"./intersect/intersect-ellipse\"),\n    intersectCircle = require(\"./intersect/intersect-circle\"),\n    intersectPolygon = require(\"./intersect/intersect-polygon\");\n\nmodule.exports = {\n  rect: rect,\n  ellipse: ellipse,\n  circle: circle,\n  diamond: diamond\n};\n\nfunction rect(parent, bbox, node) {\n  var shapeSvg = parent.insert(\"rect\", \":first-child\")\n        .attr(\"rx\", node.rx)\n        .attr(\"ry\", node.ry)\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"width\", bbox.width)\n        .attr(\"height\", bbox.height);\n\n  node.intersect = function(point) {\n    return intersectRect(node, point);\n  };\n\n  return shapeSvg;\n}\n\nfunction ellipse(parent, bbox, node) {\n  var rx = bbox.width / 2,\n      ry = bbox.height / 2,\n      shapeSvg = parent.insert(\"ellipse\", \":first-child\")\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"rx\", rx)\n        .attr(\"ry\", ry);\n\n  node.intersect = function(point) {\n    return intersectEllipse(node, rx, ry, point);\n  };\n\n  return shapeSvg;\n}\n\nfunction circle(parent, bbox, node) {\n  var r = Math.max(bbox.width, bbox.height) / 2,\n      shapeSvg = parent.insert(\"circle\", \":first-child\")\n        .attr(\"x\", -bbox.width / 2)\n        .attr(\"y\", -bbox.height / 2)\n        .attr(\"r\", r);\n\n  node.intersect = function(point) {\n    return intersectCircle(node, r, point);\n  };\n\n  return shapeSvg;\n}\n\n// Circumscribe an ellipse for the bounding box with a diamond shape. I derived\n// the function to calculate the diamond shape from:\n// http://mathforum.org/kb/message.jspa?messageID=3750236\nfunction diamond(parent, bbox, node) {\n  var w = (bbox.width * Math.SQRT2) / 2,\n      h = (bbox.height * Math.SQRT2) / 2,\n      points = [\n        { x:  0, y: -h },\n        { x: -w, y:  0 },\n        { x:  0, y:  h },\n        { x:  w, y:  0 }\n      ],\n      shapeSvg = parent.insert(\"polygon\", \":first-child\")\n        .attr(\"points\", points.map(function(p) { return p.x + \",\" + p.y; }).join(\" \"));\n\n  node.intersect = function(p) {\n    return intersectPolygon(node, points, p);\n  };\n\n  return shapeSvg;\n}\n","var _ = require(\"./lodash\");\n\n// Public utility functions\nmodule.exports = {\n  isSubgraph: isSubgraph,\n  edgeToId: edgeToId,\n  applyStyle: applyStyle,\n  applyClass: applyClass,\n  applyTransition: applyTransition\n};\n\n/*\n * Returns true if the specified node in the graph is a subgraph node. A\n * subgraph node is one that contains other nodes.\n */\nfunction isSubgraph(g, v) {\n  return !!g.children(v).length;\n}\n\nfunction edgeToId(e) {\n  return escapeId(e.v) + \":\" + escapeId(e.w) + \":\" + escapeId(e.name);\n}\n\nvar ID_DELIM = /:/g;\nfunction escapeId(str) {\n  return str ? String(str).replace(ID_DELIM, \"\\\\:\") : \"\";\n}\n\nfunction applyStyle(dom, styleFn) {\n  if (styleFn) {\n    dom.attr(\"style\", styleFn);\n  }\n}\n\nfunction applyClass(dom, classFn, otherClasses) {\n  if (classFn) {\n    dom\n      .attr(\"class\", classFn)\n      .attr(\"class\", otherClasses + \" \" + dom.attr(\"class\"));\n  }\n}\n\nfunction applyTransition(selection, g) {\n  var graph = g.graph();\n\n  if (_.isPlainObject(graph)) {\n    var transition = graph.transition;\n    if (_.isFunction(transition)) {\n      return transition(selection);\n    }\n  }\n\n  return selection;\n}\n","module.exports = \"0.4.17\";\n"],"sourceRoot":"/source/"}