exports.id = 724;
exports.ids = [724];
exports.modules = {

/***/ 84182:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(82241));
	else {}
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_643__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_643__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_643__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_643__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_643__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_643__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_643__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_643__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_643__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_643__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_643__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_643__(__nested_webpack_require_643__.s = 7);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_3185__) {

"use strict";


var FDLayoutConstants = __nested_webpack_require_3185__(0).FDLayoutConstants;

function CoSEConstants() {}

//CoSEConstants inherits static props in FDLayoutConstants
for (var prop in FDLayoutConstants) {
  CoSEConstants[prop] = FDLayoutConstants[prop];
}

CoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false;
CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
CoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60;
CoSEConstants.TILE = true;
CoSEConstants.TILING_PADDING_VERTICAL = 10;
CoSEConstants.TILING_PADDING_HORIZONTAL = 10;
CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout

module.exports = CoSEConstants;

/***/ }),
/* 2 */
/***/ (function(module, exports, __nested_webpack_require_4002__) {

"use strict";


var FDLayoutEdge = __nested_webpack_require_4002__(0).FDLayoutEdge;

function CoSEEdge(source, target, vEdge) {
  FDLayoutEdge.call(this, source, target, vEdge);
}

CoSEEdge.prototype = Object.create(FDLayoutEdge.prototype);
for (var prop in FDLayoutEdge) {
  CoSEEdge[prop] = FDLayoutEdge[prop];
}

module.exports = CoSEEdge;

/***/ }),
/* 3 */
/***/ (function(module, exports, __nested_webpack_require_4409__) {

"use strict";


var LGraph = __nested_webpack_require_4409__(0).LGraph;

function CoSEGraph(parent, graphMgr, vGraph) {
  LGraph.call(this, parent, graphMgr, vGraph);
}

CoSEGraph.prototype = Object.create(LGraph.prototype);
for (var prop in LGraph) {
  CoSEGraph[prop] = LGraph[prop];
}

module.exports = CoSEGraph;

/***/ }),
/* 4 */
/***/ (function(module, exports, __nested_webpack_require_4790__) {

"use strict";


var LGraphManager = __nested_webpack_require_4790__(0).LGraphManager;

function CoSEGraphManager(layout) {
  LGraphManager.call(this, layout);
}

CoSEGraphManager.prototype = Object.create(LGraphManager.prototype);
for (var prop in LGraphManager) {
  CoSEGraphManager[prop] = LGraphManager[prop];
}

module.exports = CoSEGraphManager;

/***/ }),
/* 5 */
/***/ (function(module, exports, __nested_webpack_require_5205__) {

"use strict";


var FDLayoutNode = __nested_webpack_require_5205__(0).FDLayoutNode;
var IMath = __nested_webpack_require_5205__(0).IMath;

function CoSENode(gm, loc, size, vNode) {
  FDLayoutNode.call(this, gm, loc, size, vNode);
}

CoSENode.prototype = Object.create(FDLayoutNode.prototype);
for (var prop in FDLayoutNode) {
  CoSENode[prop] = FDLayoutNode[prop];
}

CoSENode.prototype.move = function () {
  var layout = this.graphManager.getLayout();
  this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren;
  this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren;

  if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) {
    this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX);
  }

  if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) {
    this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY);
  }

  // a simple node, just move it
  if (this.child == null) {
    this.moveBy(this.displacementX, this.displacementY);
  }
  // an empty compound node, again just move it
  else if (this.child.getNodes().length == 0) {
      this.moveBy(this.displacementX, this.displacementY);
    }
    // non-empty compound node, propogate movement to children as well
    else {
        this.propogateDisplacementToChildren(this.displacementX, this.displacementY);
      }

  layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY);

  this.springForceX = 0;
  this.springForceY = 0;
  this.repulsionForceX = 0;
  this.repulsionForceY = 0;
  this.gravitationForceX = 0;
  this.gravitationForceY = 0;
  this.displacementX = 0;
  this.displacementY = 0;
};

CoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) {
  var nodes = this.getChild().getNodes();
  var node;
  for (var i = 0; i < nodes.length; i++) {
    node = nodes[i];
    if (node.getChild() == null) {
      node.moveBy(dX, dY);
      node.displacementX += dX;
      node.displacementY += dY;
    } else {
      node.propogateDisplacementToChildren(dX, dY);
    }
  }
};

CoSENode.prototype.setPred1 = function (pred1) {
  this.pred1 = pred1;
};

CoSENode.prototype.getPred1 = function () {
  return pred1;
};

CoSENode.prototype.getPred2 = function () {
  return pred2;
};

CoSENode.prototype.setNext = function (next) {
  this.next = next;
};

CoSENode.prototype.getNext = function () {
  return next;
};

CoSENode.prototype.setProcessed = function (processed) {
  this.processed = processed;
};

CoSENode.prototype.isProcessed = function () {
  return processed;
};

module.exports = CoSENode;

/***/ }),
/* 6 */
/***/ (function(module, exports, __nested_webpack_require_8085__) {

"use strict";


var FDLayout = __nested_webpack_require_8085__(0).FDLayout;
var CoSEGraphManager = __nested_webpack_require_8085__(4);
var CoSEGraph = __nested_webpack_require_8085__(3);
var CoSENode = __nested_webpack_require_8085__(5);
var CoSEEdge = __nested_webpack_require_8085__(2);
var CoSEConstants = __nested_webpack_require_8085__(1);
var FDLayoutConstants = __nested_webpack_require_8085__(0).FDLayoutConstants;
var LayoutConstants = __nested_webpack_require_8085__(0).LayoutConstants;
var Point = __nested_webpack_require_8085__(0).Point;
var PointD = __nested_webpack_require_8085__(0).PointD;
var Layout = __nested_webpack_require_8085__(0).Layout;
var Integer = __nested_webpack_require_8085__(0).Integer;
var IGeometry = __nested_webpack_require_8085__(0).IGeometry;
var LGraph = __nested_webpack_require_8085__(0).LGraph;
var Transform = __nested_webpack_require_8085__(0).Transform;

function CoSELayout() {
  FDLayout.call(this);

  this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled
}

CoSELayout.prototype = Object.create(FDLayout.prototype);

for (var prop in FDLayout) {
  CoSELayout[prop] = FDLayout[prop];
}

CoSELayout.prototype.newGraphManager = function () {
  var gm = new CoSEGraphManager(this);
  this.graphManager = gm;
  return gm;
};

CoSELayout.prototype.newGraph = function (vGraph) {
  return new CoSEGraph(null, this.graphManager, vGraph);
};

CoSELayout.prototype.newNode = function (vNode) {
  return new CoSENode(this.graphManager, vNode);
};

CoSELayout.prototype.newEdge = function (vEdge) {
  return new CoSEEdge(null, null, vEdge);
};

CoSELayout.prototype.initParameters = function () {
  FDLayout.prototype.initParameters.call(this, arguments);
  if (!this.isSubLayout) {
    if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) {
      this.idealEdgeLength = 10;
    } else {
      this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH;
    }

    this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;
    this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;
    this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;
    this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;
    this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;
    this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;
    this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;

    // variables for tree reduction support
    this.prunedNodesAll = [];
    this.growTreeIterations = 0;
    this.afterGrowthIterations = 0;
    this.isTreeGrowing = false;
    this.isGrowthFinished = false;

    // variables for cooling
    this.coolingCycle = 0;
    this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD;
    this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations;
    this.coolingAdjuster = 1;
  }
};

CoSELayout.prototype.layout = function () {
  var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
  if (createBendsAsNeeded) {
    this.createBendpoints();
    this.graphManager.resetAllEdges();
  }

  this.level = 0;
  return this.classicLayout();
};

CoSELayout.prototype.classicLayout = function () {
  this.nodesWithGravity = this.calculateNodesToApplyGravitationTo();
  this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity);
  this.calcNoOfChildrenForAllNodes();
  this.graphManager.calcLowestCommonAncestors();
  this.graphManager.calcInclusionTreeDepths();
  this.graphManager.getRoot().calcEstimatedSize();
  this.calcIdealEdgeLengths();

  if (!this.incremental) {
    var forest = this.getFlatForest();

    // The graph associated with this layout is flat and a forest
    if (forest.length > 0) {
      this.positionNodesRadially(forest);
    }
    // The graph associated with this layout is not flat or a forest
    else {
        // Reduce the trees when incremental mode is not enabled and graph is not a forest 
        this.reduceTrees();
        // Update nodes that gravity will be applied
        this.graphManager.resetAllNodesToApplyGravitation();
        var allNodes = new Set(this.getAllNodes());
        var intersection = this.nodesWithGravity.filter(function (x) {
          return allNodes.has(x);
        });
        this.graphManager.setAllNodesToApplyGravitation(intersection);

        this.positionNodesRandomly();
      }
  } else {
    if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) {
      // Reduce the trees in incremental mode if only this constant is set to true 
      this.reduceTrees();
      // Update nodes that gravity will be applied
      this.graphManager.resetAllNodesToApplyGravitation();
      var allNodes = new Set(this.getAllNodes());
      var intersection = this.nodesWithGravity.filter(function (x) {
        return allNodes.has(x);
      });
      this.graphManager.setAllNodesToApplyGravitation(intersection);
    }
  }

  this.initSpringEmbedder();
  this.runSpringEmbedder();

  return true;
};

CoSELayout.prototype.tick = function () {
  this.totalIterations++;

  if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) {
    if (this.prunedNodesAll.length > 0) {
      this.isTreeGrowing = true;
    } else {
      return true;
    }
  }

  if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) {
    if (this.isConverged()) {
      if (this.prunedNodesAll.length > 0) {
        this.isTreeGrowing = true;
      } else {
        return true;
      }
    }

    this.coolingCycle++;

    if (this.layoutQuality == 0) {
      // quality - "draft"
      this.coolingAdjuster = this.coolingCycle;
    } else if (this.layoutQuality == 1) {
      // quality - "default"
      this.coolingAdjuster = this.coolingCycle / 3;
    }

    // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3
    this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature);
    this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor));
  }
  // Operations while tree is growing again 
  if (this.isTreeGrowing) {
    if (this.growTreeIterations % 10 == 0) {
      if (this.prunedNodesAll.length > 0) {
        this.graphManager.updateBounds();
        this.updateGrid();
        this.growTree(this.prunedNodesAll);
        // Update nodes that gravity will be applied
        this.graphManager.resetAllNodesToApplyGravitation();
        var allNodes = new Set(this.getAllNodes());
        var intersection = this.nodesWithGravity.filter(function (x) {
          return allNodes.has(x);
        });
        this.graphManager.setAllNodesToApplyGravitation(intersection);

        this.graphManager.updateBounds();
        this.updateGrid();
        this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
      } else {
        this.isTreeGrowing = false;
        this.isGrowthFinished = true;
      }
    }
    this.growTreeIterations++;
  }
  // Operations after growth is finished
  if (this.isGrowthFinished) {
    if (this.isConverged()) {
      return true;
    }
    if (this.afterGrowthIterations % 10 == 0) {
      this.graphManager.updateBounds();
      this.updateGrid();
    }
    this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100);
    this.afterGrowthIterations++;
  }

  var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished;
  var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished;

  this.totalDisplacement = 0;
  this.graphManager.updateBounds();
  this.calcSpringForces();
  this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate);
  this.calcGravitationalForces();
  this.moveNodes();
  this.animate();

  return false; // Layout is not ended yet return false
};

CoSELayout.prototype.getPositionsData = function () {
  var allNodes = this.graphManager.getAllNodes();
  var pData = {};
  for (var i = 0; i < allNodes.length; i++) {
    var rect = allNodes[i].rect;
    var id = allNodes[i].id;
    pData[id] = {
      id: id,
      x: rect.getCenterX(),
      y: rect.getCenterY(),
      w: rect.width,
      h: rect.height
    };
  }

  return pData;
};

CoSELayout.prototype.runSpringEmbedder = function () {
  this.initialAnimationPeriod = 25;
  this.animationPeriod = this.initialAnimationPeriod;
  var layoutEnded = false;

  // If aminate option is 'during' signal that layout is supposed to start iterating
  if (FDLayoutConstants.ANIMATE === 'during') {
    this.emit('layoutstarted');
  } else {
    // If aminate option is 'during' tick() function will be called on index.js
    while (!layoutEnded) {
      layoutEnded = this.tick();
    }

    this.graphManager.updateBounds();
  }
};

CoSELayout.prototype.calculateNodesToApplyGravitationTo = function () {
  var nodeList = [];
  var graph;

  var graphs = this.graphManager.getGraphs();
  var size = graphs.length;
  var i;
  for (i = 0; i < size; i++) {
    graph = graphs[i];

    graph.updateConnected();

    if (!graph.isConnected) {
      nodeList = nodeList.concat(graph.getNodes());
    }
  }

  return nodeList;
};

CoSELayout.prototype.createBendpoints = function () {
  var edges = [];
  edges = edges.concat(this.graphManager.getAllEdges());
  var visited = new Set();
  var i;
  for (i = 0; i < edges.length; i++) {
    var edge = edges[i];

    if (!visited.has(edge)) {
      var source = edge.getSource();
      var target = edge.getTarget();

      if (source == target) {
        edge.getBendpoints().push(new PointD());
        edge.getBendpoints().push(new PointD());
        this.createDummyNodesForBendpoints(edge);
        visited.add(edge);
      } else {
        var edgeList = [];

        edgeList = edgeList.concat(source.getEdgeListToNode(target));
        edgeList = edgeList.concat(target.getEdgeListToNode(source));

        if (!visited.has(edgeList[0])) {
          if (edgeList.length > 1) {
            var k;
            for (k = 0; k < edgeList.length; k++) {
              var multiEdge = edgeList[k];
              multiEdge.getBendpoints().push(new PointD());
              this.createDummyNodesForBendpoints(multiEdge);
            }
          }
          edgeList.forEach(function (edge) {
            visited.add(edge);
          });
        }
      }
    }

    if (visited.size == edges.length) {
      break;
    }
  }
};

CoSELayout.prototype.positionNodesRadially = function (forest) {
  // We tile the trees to a grid row by row; first tree starts at (0,0)
  var currentStartingPoint = new Point(0, 0);
  var numberOfColumns = Math.ceil(Math.sqrt(forest.length));
  var height = 0;
  var currentY = 0;
  var currentX = 0;
  var point = new PointD(0, 0);

  for (var i = 0; i < forest.length; i++) {
    if (i % numberOfColumns == 0) {
      // Start of a new row, make the x coordinate 0, increment the
      // y coordinate with the max height of the previous row
      currentX = 0;
      currentY = height;

      if (i != 0) {
        currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION;
      }

      height = 0;
    }

    var tree = forest[i];

    // Find the center of the tree
    var centerNode = Layout.findCenterOfTree(tree);

    // Set the staring point of the next tree
    currentStartingPoint.x = currentX;
    currentStartingPoint.y = currentY;

    // Do a radial layout starting with the center
    point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint);

    if (point.y > height) {
      height = Math.floor(point.y);
    }

    currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION);
  }

  this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2));
};

CoSELayout.radialLayout = function (tree, centerNode, startingPoint) {
  var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION);
  CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep);
  var bounds = LGraph.calculateBounds(tree);

  var transform = new Transform();
  transform.setDeviceOrgX(bounds.getMinX());
  transform.setDeviceOrgY(bounds.getMinY());
  transform.setWorldOrgX(startingPoint.x);
  transform.setWorldOrgY(startingPoint.y);

  for (var i = 0; i < tree.length; i++) {
    var node = tree[i];
    node.transform(transform);
  }

  var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY());

  return transform.inverseTransformPoint(bottomRight);
};

CoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) {
  // First, position this node by finding its angle.
  var halfInterval = (endAngle - startAngle + 1) / 2;

  if (halfInterval < 0) {
    halfInterval += 180;
  }

  var nodeAngle = (halfInterval + startAngle) % 360;
  var teta = nodeAngle * IGeometry.TWO_PI / 360;

  // Make polar to java cordinate conversion.
  var cos_teta = Math.cos(teta);
  var x_ = distance * Math.cos(teta);
  var y_ = distance * Math.sin(teta);

  node.setCenter(x_, y_);

  // Traverse all neighbors of this node and recursively call this
  // function.
  var neighborEdges = [];
  neighborEdges = neighborEdges.concat(node.getEdges());
  var childCount = neighborEdges.length;

  if (parentOfNode != null) {
    childCount--;
  }

  var branchCount = 0;

  var incEdgesCount = neighborEdges.length;
  var startIndex;

  var edges = node.getEdgesBetween(parentOfNode);

  // If there are multiple edges, prune them until there remains only one
  // edge.
  while (edges.length > 1) {
    //neighborEdges.remove(edges.remove(0));
    var temp = edges[0];
    edges.splice(0, 1);
    var index = neighborEdges.indexOf(temp);
    if (index >= 0) {
      neighborEdges.splice(index, 1);
    }
    incEdgesCount--;
    childCount--;
  }

  if (parentOfNode != null) {
    //assert edges.length == 1;
    startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount;
  } else {
    startIndex = 0;
  }

  var stepAngle = Math.abs(endAngle - startAngle) / childCount;

  for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) {
    var currentNeighbor = neighborEdges[i].getOtherEnd(node);

    // Don't back traverse to root node in current tree.
    if (currentNeighbor == parentOfNode) {
      continue;
    }

    var childStartAngle = (startAngle + branchCount * stepAngle) % 360;
    var childEndAngle = (childStartAngle + stepAngle) % 360;

    CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation);

    branchCount++;
  }
};

CoSELayout.maxDiagonalInTree = function (tree) {
  var maxDiagonal = Integer.MIN_VALUE;

  for (var i = 0; i < tree.length; i++) {
    var node = tree[i];
    var diagonal = node.getDiagonal();

    if (diagonal > maxDiagonal) {
      maxDiagonal = diagonal;
    }
  }

  return maxDiagonal;
};

CoSELayout.prototype.calcRepulsionRange = function () {
  // formula is 2 x (level + 1) x idealEdgeLength
  return 2 * (this.level + 1) * this.idealEdgeLength;
};

// Tiling methods

// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's
CoSELayout.prototype.groupZeroDegreeMembers = function () {
  var self = this;
  // array of [parent_id x oneDegreeNode_id]
  var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members
  this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled
  this.idToDummyNode = {}; // A map of id to dummy node 

  var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled
  var allNodes = this.graphManager.getAllNodes();

  // Fill zero degree list
  for (var i = 0; i < allNodes.length; i++) {
    var node = allNodes[i];
    var parent = node.getParent();
    // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list
    if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) {
      zeroDegree.push(node);
    }
  }

  // Create a map of parent node and its zero degree members
  for (var i = 0; i < zeroDegree.length; i++) {
    var node = zeroDegree[i]; // Zero degree node itself
    var p_id = node.getParent().id; // Parent id

    if (typeof tempMemberGroups[p_id] === "undefined") tempMemberGroups[p_id] = [];

    tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups
  }

  // If there are at least two nodes at a level, create a dummy compound for them
  Object.keys(tempMemberGroups).forEach(function (p_id) {
    if (tempMemberGroups[p_id].length > 1) {
      var dummyCompoundId = "DummyCompound_" + p_id; // The id of dummy compound which will be created soon
      self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups

      var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound

      // Create a dummy compound with calculated id
      var dummyCompound = new CoSENode(self.graphManager);
      dummyCompound.id = dummyCompoundId;
      dummyCompound.paddingLeft = parent.paddingLeft || 0;
      dummyCompound.paddingRight = parent.paddingRight || 0;
      dummyCompound.paddingBottom = parent.paddingBottom || 0;
      dummyCompound.paddingTop = parent.paddingTop || 0;

      self.idToDummyNode[dummyCompoundId] = dummyCompound;

      var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound);
      var parentGraph = parent.getChild();

      // Add dummy compound to parent the graph
      parentGraph.add(dummyCompound);

      // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent
      for (var i = 0; i < tempMemberGroups[p_id].length; i++) {
        var node = tempMemberGroups[p_id][i];

        parentGraph.remove(node);
        dummyParentGraph.add(node);
      }
    }
  });
};

CoSELayout.prototype.clearCompounds = function () {
  var childGraphMap = {};
  var idToNode = {};

  // Get compound ordering by finding the inner one first
  this.performDFSOnCompounds();

  for (var i = 0; i < this.compoundOrder.length; i++) {

    idToNode[this.compoundOrder[i].id] = this.compoundOrder[i];
    childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes());

    // Remove children of compounds
    this.graphManager.remove(this.compoundOrder[i].getChild());
    this.compoundOrder[i].child = null;
  }

  this.graphManager.resetAllNodes();

  // Tile the removed children
  this.tileCompoundMembers(childGraphMap, idToNode);
};

CoSELayout.prototype.clearZeroDegreeMembers = function () {
  var self = this;
  var tiledZeroDegreePack = this.tiledZeroDegreePack = [];

  Object.keys(this.memberGroups).forEach(function (id) {
    var compoundNode = self.idToDummyNode[id]; // Get the dummy compound

    tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight);

    // Set the width and height of the dummy compound as calculated
    compoundNode.rect.width = tiledZeroDegreePack[id].width;
    compoundNode.rect.height = tiledZeroDegreePack[id].height;
  });
};

CoSELayout.prototype.repopulateCompounds = function () {
  for (var i = this.compoundOrder.length - 1; i >= 0; i--) {
    var lCompoundNode = this.compoundOrder[i];
    var id = lCompoundNode.id;
    var horizontalMargin = lCompoundNode.paddingLeft;
    var verticalMargin = lCompoundNode.paddingTop;

    this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin);
  }
};

CoSELayout.prototype.repopulateZeroDegreeMembers = function () {
  var self = this;
  var tiledPack = this.tiledZeroDegreePack;

  Object.keys(tiledPack).forEach(function (id) {
    var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id
    var horizontalMargin = compoundNode.paddingLeft;
    var verticalMargin = compoundNode.paddingTop;

    // Adjust the positions of nodes wrt its compound
    self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin);
  });
};

CoSELayout.prototype.getToBeTiled = function (node) {
  var id = node.id;
  //firstly check the previous results
  if (this.toBeTiled[id] != null) {
    return this.toBeTiled[id];
  }

  //only compound nodes are to be tiled
  var childGraph = node.getChild();
  if (childGraph == null) {
    this.toBeTiled[id] = false;
    return false;
  }

  var children = childGraph.getNodes(); // Get the children nodes

  //a compound node is not to be tiled if all of its compound children are not to be tiled
  for (var i = 0; i < children.length; i++) {
    var theChild = children[i];

    if (this.getNodeDegree(theChild) > 0) {
      this.toBeTiled[id] = false;
      return false;
    }

    //pass the children not having the compound structure
    if (theChild.getChild() == null) {
      this.toBeTiled[theChild.id] = false;
      continue;
    }

    if (!this.getToBeTiled(theChild)) {
      this.toBeTiled[id] = false;
      return false;
    }
  }
  this.toBeTiled[id] = true;
  return true;
};

// Get degree of a node depending of its edges and independent of its children
CoSELayout.prototype.getNodeDegree = function (node) {
  var id = node.id;
  var edges = node.getEdges();
  var degree = 0;

  // For the edges connected
  for (var i = 0; i < edges.length; i++) {
    var edge = edges[i];
    if (edge.getSource().id !== edge.getTarget().id) {
      degree = degree + 1;
    }
  }
  return degree;
};

// Get degree of a node with its children
CoSELayout.prototype.getNodeDegreeWithChildren = function (node) {
  var degree = this.getNodeDegree(node);
  if (node.getChild() == null) {
    return degree;
  }
  var children = node.getChild().getNodes();
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    degree += this.getNodeDegreeWithChildren(child);
  }
  return degree;
};

CoSELayout.prototype.performDFSOnCompounds = function () {
  this.compoundOrder = [];
  this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes());
};

CoSELayout.prototype.fillCompexOrderByDFS = function (children) {
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    if (child.getChild() != null) {
      this.fillCompexOrderByDFS(child.getChild().getNodes());
    }
    if (this.getToBeTiled(child)) {
      this.compoundOrder.push(child);
    }
  }
};

/**
* This method places each zero degree member wrt given (x,y) coordinates (top left).
*/
CoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) {
  x += compoundHorizontalMargin;
  y += compoundVerticalMargin;

  var left = x;

  for (var i = 0; i < organization.rows.length; i++) {
    var row = organization.rows[i];
    x = left;
    var maxHeight = 0;

    for (var j = 0; j < row.length; j++) {
      var lnode = row[j];

      lnode.rect.x = x; // + lnode.rect.width / 2;
      lnode.rect.y = y; // + lnode.rect.height / 2;

      x += lnode.rect.width + organization.horizontalPadding;

      if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height;
    }

    y += maxHeight + organization.verticalPadding;
  }
};

CoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) {
  var self = this;
  this.tiledMemberPack = [];

  Object.keys(childGraphMap).forEach(function (id) {
    // Get the compound node
    var compoundNode = idToNode[id];

    self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight);

    compoundNode.rect.width = self.tiledMemberPack[id].width;
    compoundNode.rect.height = self.tiledMemberPack[id].height;
  });
};

CoSELayout.prototype.tileNodes = function (nodes, minWidth) {
  var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;
  var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;
  var organization = {
    rows: [],
    rowWidth: [],
    rowHeight: [],
    width: 0,
    height: minWidth, // assume minHeight equals to minWidth
    verticalPadding: verticalPadding,
    horizontalPadding: horizontalPadding
  };

  // Sort the nodes in ascending order of their areas
  nodes.sort(function (n1, n2) {
    if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1;
    if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1;
    return 0;
  });

  // Create the organization -> tile members
  for (var i = 0; i < nodes.length; i++) {
    var lNode = nodes[i];

    if (organization.rows.length == 0) {
      this.insertNodeToRow(organization, lNode, 0, minWidth);
    } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) {
      this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth);
    } else {
      this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth);
    }

    this.shiftToLastRow(organization);
  }

  return organization;
};

CoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) {
  var minCompoundSize = minWidth;

  // Add new row if needed
  if (rowIndex == organization.rows.length) {
    var secondDimension = [];

    organization.rows.push(secondDimension);
    organization.rowWidth.push(minCompoundSize);
    organization.rowHeight.push(0);
  }

  // Update row width
  var w = organization.rowWidth[rowIndex] + node.rect.width;

  if (organization.rows[rowIndex].length > 0) {
    w += organization.horizontalPadding;
  }

  organization.rowWidth[rowIndex] = w;
  // Update compound width
  if (organization.width < w) {
    organization.width = w;
  }

  // Update height
  var h = node.rect.height;
  if (rowIndex > 0) h += organization.verticalPadding;

  var extraHeight = 0;
  if (h > organization.rowHeight[rowIndex]) {
    extraHeight = organization.rowHeight[rowIndex];
    organization.rowHeight[rowIndex] = h;
    extraHeight = organization.rowHeight[rowIndex] - extraHeight;
  }

  organization.height += extraHeight;

  // Insert node
  organization.rows[rowIndex].push(node);
};

//Scans the rows of an organization and returns the one with the min width
CoSELayout.prototype.getShortestRowIndex = function (organization) {
  var r = -1;
  var min = Number.MAX_VALUE;

  for (var i = 0; i < organization.rows.length; i++) {
    if (organization.rowWidth[i] < min) {
      r = i;
      min = organization.rowWidth[i];
    }
  }
  return r;
};

//Scans the rows of an organization and returns the one with the max width
CoSELayout.prototype.getLongestRowIndex = function (organization) {
  var r = -1;
  var max = Number.MIN_VALUE;

  for (var i = 0; i < organization.rows.length; i++) {

    if (organization.rowWidth[i] > max) {
      r = i;
      max = organization.rowWidth[i];
    }
  }

  return r;
};

/**
* This method checks whether adding extra width to the organization violates
* the aspect ratio(1) or not.
*/
CoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) {

  var sri = this.getShortestRowIndex(organization);

  if (sri < 0) {
    return true;
  }

  var min = organization.rowWidth[sri];

  if (min + organization.horizontalPadding + extraWidth <= organization.width) return true;

  var hDiff = 0;

  // Adding to an existing row
  if (organization.rowHeight[sri] < extraHeight) {
    if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri];
  }

  var add_to_row_ratio;
  if (organization.width - min >= extraWidth + organization.horizontalPadding) {
    add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding);
  } else {
    add_to_row_ratio = (organization.height + hDiff) / organization.width;
  }

  // Adding a new row for this node
  hDiff = extraHeight + organization.verticalPadding;
  var add_new_row_ratio;
  if (organization.width < extraWidth) {
    add_new_row_ratio = (organization.height + hDiff) / extraWidth;
  } else {
    add_new_row_ratio = (organization.height + hDiff) / organization.width;
  }

  if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio;

  if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio;

  return add_to_row_ratio < add_new_row_ratio;
};

//If moving the last node from the longest row and adding it to the last
//row makes the bounding box smaller, do it.
CoSELayout.prototype.shiftToLastRow = function (organization) {
  var longest = this.getLongestRowIndex(organization);
  var last = organization.rowWidth.length - 1;
  var row = organization.rows[longest];
  var node = row[row.length - 1];

  var diff = node.width + organization.horizontalPadding;

  // Check if there is enough space on the last row
  if (organization.width - organization.rowWidth[last] > diff && longest != last) {
    // Remove the last element of the longest row
    row.splice(-1, 1);

    // Push it to the last row
    organization.rows[last].push(node);

    organization.rowWidth[longest] = organization.rowWidth[longest] - diff;
    organization.rowWidth[last] = organization.rowWidth[last] + diff;
    organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)];

    // Update heights of the organization
    var maxHeight = Number.MIN_VALUE;
    for (var i = 0; i < row.length; i++) {
      if (row[i].height > maxHeight) maxHeight = row[i].height;
    }
    if (longest > 0) maxHeight += organization.verticalPadding;

    var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last];

    organization.rowHeight[longest] = maxHeight;
    if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding;

    var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last];
    organization.height += finalTotal - prevTotal;

    this.shiftToLastRow(organization);
  }
};

CoSELayout.prototype.tilingPreLayout = function () {
  if (CoSEConstants.TILE) {
    // Find zero degree nodes and create a compound for each level
    this.groupZeroDegreeMembers();
    // Tile and clear children of each compound
    this.clearCompounds();
    // Separately tile and clear zero degree nodes for each level
    this.clearZeroDegreeMembers();
  }
};

CoSELayout.prototype.tilingPostLayout = function () {
  if (CoSEConstants.TILE) {
    this.repopulateZeroDegreeMembers();
    this.repopulateCompounds();
  }
};

// -----------------------------------------------------------------------------
// Section: Tree Reduction methods
// -----------------------------------------------------------------------------
// Reduce trees 
CoSELayout.prototype.reduceTrees = function () {
  var prunedNodesAll = [];
  var containsLeaf = true;
  var node;

  while (containsLeaf) {
    var allNodes = this.graphManager.getAllNodes();
    var prunedNodesInStepTemp = [];
    containsLeaf = false;

    for (var i = 0; i < allNodes.length; i++) {
      node = allNodes[i];
      if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) {
        prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]);
        containsLeaf = true;
      }
    }
    if (containsLeaf == true) {
      var prunedNodesInStep = [];
      for (var j = 0; j < prunedNodesInStepTemp.length; j++) {
        if (prunedNodesInStepTemp[j][0].getEdges().length == 1) {
          prunedNodesInStep.push(prunedNodesInStepTemp[j]);
          prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]);
        }
      }
      prunedNodesAll.push(prunedNodesInStep);
      this.graphManager.resetAllNodes();
      this.graphManager.resetAllEdges();
    }
  }
  this.prunedNodesAll = prunedNodesAll;
};

// Grow tree one step 
CoSELayout.prototype.growTree = function (prunedNodesAll) {
  var lengthOfPrunedNodesInStep = prunedNodesAll.length;
  var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1];

  var nodeData;
  for (var i = 0; i < prunedNodesInStep.length; i++) {
    nodeData = prunedNodesInStep[i];

    this.findPlaceforPrunedNode(nodeData);

    nodeData[2].add(nodeData[0]);
    nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target);
  }

  prunedNodesAll.splice(prunedNodesAll.length - 1, 1);
  this.graphManager.resetAllNodes();
  this.graphManager.resetAllEdges();
};

// Find an appropriate position to replace pruned node, this method can be improved
CoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) {

  var gridForPrunedNode;
  var nodeToConnect;
  var prunedNode = nodeData[0];
  if (prunedNode == nodeData[1].source) {
    nodeToConnect = nodeData[1].target;
  } else {
    nodeToConnect = nodeData[1].source;
  }
  var startGridX = nodeToConnect.startX;
  var finishGridX = nodeToConnect.finishX;
  var startGridY = nodeToConnect.startY;
  var finishGridY = nodeToConnect.finishY;

  var upNodeCount = 0;
  var downNodeCount = 0;
  var rightNodeCount = 0;
  var leftNodeCount = 0;
  var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount];

  if (startGridY > 0) {
    for (var i = startGridX; i <= finishGridX; i++) {
      controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1;
    }
  }
  if (finishGridX < this.grid.length - 1) {
    for (var i = startGridY; i <= finishGridY; i++) {
      controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1;
    }
  }
  if (finishGridY < this.grid[0].length - 1) {
    for (var i = startGridX; i <= finishGridX; i++) {
      controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1;
    }
  }
  if (startGridX > 0) {
    for (var i = startGridY; i <= finishGridY; i++) {
      controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1;
    }
  }
  var min = Integer.MAX_VALUE;
  var minCount;
  var minIndex;
  for (var j = 0; j < controlRegions.length; j++) {
    if (controlRegions[j] < min) {
      min = controlRegions[j];
      minCount = 1;
      minIndex = j;
    } else if (controlRegions[j] == min) {
      minCount++;
    }
  }

  if (minCount == 3 && min == 0) {
    if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) {
      gridForPrunedNode = 1;
    } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 0;
    } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 3;
    } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 2;
    }
  } else if (minCount == 2 && min == 0) {
    var random = Math.floor(Math.random() * 2);
    if (controlRegions[0] == 0 && controlRegions[1] == 0) {
      ;
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 1;
      }
    } else if (controlRegions[0] == 0 && controlRegions[2] == 0) {
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 2;
      }
    } else if (controlRegions[0] == 0 && controlRegions[3] == 0) {
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 3;
      }
    } else if (controlRegions[1] == 0 && controlRegions[2] == 0) {
      if (random == 0) {
        gridForPrunedNode = 1;
      } else {
        gridForPrunedNode = 2;
      }
    } else if (controlRegions[1] == 0 && controlRegions[3] == 0) {
      if (random == 0) {
        gridForPrunedNode = 1;
      } else {
        gridForPrunedNode = 3;
      }
    } else {
      if (random == 0) {
        gridForPrunedNode = 2;
      } else {
        gridForPrunedNode = 3;
      }
    }
  } else if (minCount == 4 && min == 0) {
    var random = Math.floor(Math.random() * 4);
    gridForPrunedNode = random;
  } else {
    gridForPrunedNode = minIndex;
  }

  if (gridForPrunedNode == 0) {
    prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2);
  } else if (gridForPrunedNode == 1) {
    prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
  } else if (gridForPrunedNode == 2) {
    prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2);
  } else {
    prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
  }
};

module.exports = CoSELayout;

/***/ }),
/* 7 */
/***/ (function(module, exports, __nested_webpack_require_45620__) {

"use strict";


var coseBase = {};

coseBase.layoutBase = __nested_webpack_require_45620__(0);
coseBase.CoSEConstants = __nested_webpack_require_45620__(1);
coseBase.CoSEEdge = __nested_webpack_require_45620__(2);
coseBase.CoSEGraph = __nested_webpack_require_45620__(3);
coseBase.CoSEGraphManager = __nested_webpack_require_45620__(4);
coseBase.CoSELayout = __nested_webpack_require_45620__(6);
coseBase.CoSENode = __nested_webpack_require_45620__(5);

module.exports = coseBase;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 14607:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(84182));
	else {}
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_659__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_659__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_659__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_659__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_659__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_659__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_659__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_659__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_659__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_659__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_659__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_659__(__nested_webpack_require_659__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_3201__) {

"use strict";


var LayoutConstants = __nested_webpack_require_3201__(0).layoutBase.LayoutConstants;
var FDLayoutConstants = __nested_webpack_require_3201__(0).layoutBase.FDLayoutConstants;
var CoSEConstants = __nested_webpack_require_3201__(0).CoSEConstants;
var CoSELayout = __nested_webpack_require_3201__(0).CoSELayout;
var CoSENode = __nested_webpack_require_3201__(0).CoSENode;
var PointD = __nested_webpack_require_3201__(0).layoutBase.PointD;
var DimensionD = __nested_webpack_require_3201__(0).layoutBase.DimensionD;

var defaults = {
  // Called on `layoutready`
  ready: function ready() {},
  // Called on `layoutstop`
  stop: function stop() {},
  // 'draft', 'default' or 'proof" 
  // - 'draft' fast cooling rate 
  // - 'default' moderate cooling rate 
  // - "proof" slow cooling rate
  quality: 'default',
  // include labels in node dimensions
  nodeDimensionsIncludeLabels: false,
  // number of ticks per frame; higher is faster but more jerky
  refresh: 30,
  // Whether to fit the network view after when done
  fit: true,
  // Padding on fit
  padding: 10,
  // Whether to enable incremental mode
  randomize: true,
  // Node repulsion (non overlapping) multiplier
  nodeRepulsion: 4500,
  // Ideal edge (non nested) length
  idealEdgeLength: 50,
  // Divisor to compute edge forces
  edgeElasticity: 0.45,
  // Nesting factor (multiplier) to compute ideal edge length for nested edges
  nestingFactor: 0.1,
  // Gravity force (constant)
  gravity: 0.25,
  // Maximum number of iterations to perform
  numIter: 2500,
  // For enabling tiling
  tile: true,
  // Type of layout animation. The option set is {'during', 'end', false}
  animate: 'end',
  // Duration for animate:end
  animationDuration: 500,
  // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)
  tilingPaddingVertical: 10,
  // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)
  tilingPaddingHorizontal: 10,
  // Gravity range (constant) for compounds
  gravityRangeCompound: 1.5,
  // Gravity force (constant) for compounds
  gravityCompound: 1.0,
  // Gravity range (constant)
  gravityRange: 3.8,
  // Initial cooling factor for incremental layout
  initialEnergyOnIncremental: 0.5
};

function extend(defaults, options) {
  var obj = {};

  for (var i in defaults) {
    obj[i] = defaults[i];
  }

  for (var i in options) {
    obj[i] = options[i];
  }

  return obj;
};

function _CoSELayout(_options) {
  this.options = extend(defaults, _options);
  getUserOptions(this.options);
}

var getUserOptions = function getUserOptions(options) {
  if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion;
  if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;
  if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity;
  if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;
  if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;
  if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;
  if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;
  if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;
  if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;
  if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;

  if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1;

  CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;
  CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize;
  CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;
  CoSEConstants.TILE = options.tile;
  CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;
  CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;
};

_CoSELayout.prototype.run = function () {
  var ready;
  var frameId;
  var options = this.options;
  var idToLNode = this.idToLNode = {};
  var layout = this.layout = new CoSELayout();
  var self = this;

  self.stopped = false;

  this.cy = this.options.cy;

  this.cy.trigger({ type: 'layoutstart', layout: this });

  var gm = layout.newGraphManager();
  this.gm = gm;

  var nodes = this.options.eles.nodes();
  var edges = this.options.eles.edges();

  this.root = gm.addRoot();
  this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout);

  for (var i = 0; i < edges.length; i++) {
    var edge = edges[i];
    var sourceNode = this.idToLNode[edge.data("source")];
    var targetNode = this.idToLNode[edge.data("target")];
    if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {
      var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);
      e1.id = edge.id();
    }
  }

  var getPositions = function getPositions(ele, i) {
    if (typeof ele === "number") {
      ele = i;
    }
    var theId = ele.data('id');
    var lNode = self.idToLNode[theId];

    return {
      x: lNode.getRect().getCenterX(),
      y: lNode.getRect().getCenterY()
    };
  };

  /*
   * Reposition nodes in iterations animatedly
   */
  var iterateAnimated = function iterateAnimated() {
    // Thigs to perform after nodes are repositioned on screen
    var afterReposition = function afterReposition() {
      if (options.fit) {
        options.cy.fit(options.eles, options.padding);
      }

      if (!ready) {
        ready = true;
        self.cy.one('layoutready', options.ready);
        self.cy.trigger({ type: 'layoutready', layout: self });
      }
    };

    var ticksPerFrame = self.options.refresh;
    var isDone;

    for (var i = 0; i < ticksPerFrame && !isDone; i++) {
      isDone = self.stopped || self.layout.tick();
    }

    // If layout is done
    if (isDone) {
      // If the layout is not a sublayout and it is successful perform post layout.
      if (layout.checkLayoutSuccess() && !layout.isSubLayout) {
        layout.doPostLayout();
      }

      // If layout has a tilingPostLayout function property call it.
      if (layout.tilingPostLayout) {
        layout.tilingPostLayout();
      }

      layout.isLayoutFinished = true;

      self.options.eles.nodes().positions(getPositions);

      afterReposition();

      // trigger layoutstop when the layout stops (e.g. finishes)
      self.cy.one('layoutstop', self.options.stop);
      self.cy.trigger({ type: 'layoutstop', layout: self });

      if (frameId) {
        cancelAnimationFrame(frameId);
      }

      ready = false;
      return;
    }

    var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling

    // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds)
    // use position of their ancestors or dummy ancestors
    options.eles.nodes().positions(function (ele, i) {
      if (typeof ele === "number") {
        ele = i;
      }
      // If ele is a compound node, then its position will be defined by its children
      if (!ele.isParent()) {
        var theId = ele.id();
        var pNode = animationData[theId];
        var temp = ele;
        // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well)
        while (pNode == null) {
          pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')];
          animationData[theId] = pNode;
          temp = temp.parent()[0];
          if (temp == undefined) {
            break;
          }
        }
        if (pNode != null) {
          return {
            x: pNode.x,
            y: pNode.y
          };
        } else {
          return {
            x: ele.position('x'),
            y: ele.position('y')
          };
        }
      }
    });

    afterReposition();

    frameId = requestAnimationFrame(iterateAnimated);
  };

  /*
  * Listen 'layoutstarted' event and start animated iteration if animate option is 'during'
  */
  layout.addListener('layoutstarted', function () {
    if (self.options.animate === 'during') {
      frameId = requestAnimationFrame(iterateAnimated);
    }
  });

  layout.runLayout(); // Run cose layout

  /*
   * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed)
   */
  if (this.options.animate !== "during") {
    self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter
    ready = false;
  }

  return this; // chaining
};

//Get the top most ones of a list of nodes
_CoSELayout.prototype.getTopMostNodes = function (nodes) {
  var nodesMap = {};
  for (var i = 0; i < nodes.length; i++) {
    nodesMap[nodes[i].id()] = true;
  }
  var roots = nodes.filter(function (ele, i) {
    if (typeof ele === "number") {
      ele = i;
    }
    var parent = ele.parent()[0];
    while (parent != null) {
      if (nodesMap[parent.id()]) {
        return false;
      }
      parent = parent.parent()[0];
    }
    return true;
  });

  return roots;
};

_CoSELayout.prototype.processChildrenList = function (parent, children, layout) {
  var size = children.length;
  for (var i = 0; i < size; i++) {
    var theChild = children[i];
    var children_of_children = theChild.children();
    var theNode;

    var dimensions = theChild.layoutDimensions({
      nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels
    });

    if (theChild.outerWidth() != null && theChild.outerHeight() != null) {
      theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
    } else {
      theNode = parent.add(new CoSENode(this.graphManager));
    }
    // Attach id to the layout node
    theNode.id = theChild.data("id");
    // Attach the paddings of cy node to layout node
    theNode.paddingLeft = parseInt(theChild.css('padding'));
    theNode.paddingTop = parseInt(theChild.css('padding'));
    theNode.paddingRight = parseInt(theChild.css('padding'));
    theNode.paddingBottom = parseInt(theChild.css('padding'));

    //Attach the label properties to compound if labels will be included in node dimensions  
    if (this.options.nodeDimensionsIncludeLabels) {
      if (theChild.isParent()) {
        var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w;
        var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h;
        var labelPos = theChild.css("text-halign");
        theNode.labelWidth = labelWidth;
        theNode.labelHeight = labelHeight;
        theNode.labelPos = labelPos;
      }
    }

    // Map the layout node
    this.idToLNode[theChild.data("id")] = theNode;

    if (isNaN(theNode.rect.x)) {
      theNode.rect.x = 0;
    }

    if (isNaN(theNode.rect.y)) {
      theNode.rect.y = 0;
    }

    if (children_of_children != null && children_of_children.length > 0) {
      var theNewGraph;
      theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);
      this.processChildrenList(theNewGraph, children_of_children, layout);
    }
  }
};

/**
 * @brief : called on continuous layouts to stop them before they finish
 */
_CoSELayout.prototype.stop = function () {
  this.stopped = true;

  return this; // chaining
};

var register = function register(cytoscape) {
  //  var Layout = getLayout( cytoscape );

  cytoscape('layout', 'cose-bilkent', _CoSELayout);
};

// auto reg for globals
if (typeof cytoscape !== 'undefined') {
  register(cytoscape);
}

module.exports = register;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 71377:
/***/ (function(module) {

/**
 * Copyright (c) 2016-2023, The Cytoscape Consortium.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the “Software”), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

(function (global, factory) {
   true ? module.exports = factory() :
  0;
})(this, (function () { 'use strict';

  function _typeof(obj) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
      return typeof obj;
    } : function (obj) {
      return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
    }, _typeof(obj);
  }
  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }
  function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }
  function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    Object.defineProperty(Constructor, "prototype", {
      writable: false
    });
    return Constructor;
  }
  function _defineProperty$1(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }
    return obj;
  }
  function _slicedToArray(arr, i) {
    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  }
  function _arrayWithHoles(arr) {
    if (Array.isArray(arr)) return arr;
  }
  function _iterableToArrayLimit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);
        if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;
      _e = err;
    } finally {
      try {
        if (!_n && _i["return"] != null) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }
    return _arr;
  }
  function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  }
  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
    return arr2;
  }
  function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  var _window = typeof window === 'undefined' ? null : window; // eslint-disable-line no-undef

  var navigator = _window ? _window.navigator : null;
  _window ? _window.document : null;
  var typeofstr = _typeof('');
  var typeofobj = _typeof({});
  var typeoffn = _typeof(function () {});
  var typeofhtmlele = typeof HTMLElement === "undefined" ? "undefined" : _typeof(HTMLElement);
  var instanceStr = function instanceStr(obj) {
    return obj && obj.instanceString && fn$6(obj.instanceString) ? obj.instanceString() : null;
  };

  var string = function string(obj) {
    return obj != null && _typeof(obj) == typeofstr;
  };
  var fn$6 = function fn(obj) {
    return obj != null && _typeof(obj) === typeoffn;
  };
  var array = function array(obj) {
    return !elementOrCollection(obj) && (Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array);
  };
  var plainObject = function plainObject(obj) {
    return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;
  };
  var object = function object(obj) {
    return obj != null && _typeof(obj) === typeofobj;
  };
  var number$1 = function number(obj) {
    return obj != null && _typeof(obj) === _typeof(1) && !isNaN(obj);
  };
  var integer = function integer(obj) {
    return number$1(obj) && Math.floor(obj) === obj;
  };
  var htmlElement = function htmlElement(obj) {
    if ('undefined' === typeofhtmlele) {
      return undefined;
    } else {
      return null != obj && obj instanceof HTMLElement;
    }
  };
  var elementOrCollection = function elementOrCollection(obj) {
    return element(obj) || collection(obj);
  };
  var element = function element(obj) {
    return instanceStr(obj) === 'collection' && obj._private.single;
  };
  var collection = function collection(obj) {
    return instanceStr(obj) === 'collection' && !obj._private.single;
  };
  var core = function core(obj) {
    return instanceStr(obj) === 'core';
  };
  var stylesheet = function stylesheet(obj) {
    return instanceStr(obj) === 'stylesheet';
  };
  var event = function event(obj) {
    return instanceStr(obj) === 'event';
  };
  var emptyString = function emptyString(obj) {
    if (obj === undefined || obj === null) {
      // null is empty
      return true;
    } else if (obj === '' || obj.match(/^\s+$/)) {
      return true; // empty string is empty
    }

    return false; // otherwise, we don't know what we've got
  };
  var domElement = function domElement(obj) {
    if (typeof HTMLElement === 'undefined') {
      return false; // we're not in a browser so it doesn't matter
    } else {
      return obj instanceof HTMLElement;
    }
  };
  var boundingBox = function boundingBox(obj) {
    return plainObject(obj) && number$1(obj.x1) && number$1(obj.x2) && number$1(obj.y1) && number$1(obj.y2);
  };
  var promise = function promise(obj) {
    return object(obj) && fn$6(obj.then);
  };
  var ms = function ms() {
    return navigator && navigator.userAgent.match(/msie|trident|edge/i);
  }; // probably a better way to detect this...

  var memoize$1 = function memoize(fn, keyFn) {
    if (!keyFn) {
      keyFn = function keyFn() {
        if (arguments.length === 1) {
          return arguments[0];
        } else if (arguments.length === 0) {
          return 'undefined';
        }
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
        return args.join('$');
      };
    }
    var memoizedFn = function memoizedFn() {
      var self = this;
      var args = arguments;
      var ret;
      var k = keyFn.apply(self, args);
      var cache = memoizedFn.cache;
      if (!(ret = cache[k])) {
        ret = cache[k] = fn.apply(self, args);
      }
      return ret;
    };
    memoizedFn.cache = {};
    return memoizedFn;
  };

  var camel2dash = memoize$1(function (str) {
    return str.replace(/([A-Z])/g, function (v) {
      return '-' + v.toLowerCase();
    });
  });
  var dash2camel = memoize$1(function (str) {
    return str.replace(/(-\w)/g, function (v) {
      return v[1].toUpperCase();
    });
  });
  var prependCamel = memoize$1(function (prefix, str) {
    return prefix + str[0].toUpperCase() + str.substring(1);
  }, function (prefix, str) {
    return prefix + '$' + str;
  });
  var capitalize = function capitalize(str) {
    if (emptyString(str)) {
      return str;
    }
    return str.charAt(0).toUpperCase() + str.substring(1);
  };

  var number = '(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))';
  var rgba = 'rgb[a]?\\((' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)(?:\\s*,\\s*(' + number + '))?\\)';
  var rgbaNoBackRefs = 'rgb[a]?\\((?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)(?:\\s*,\\s*(?:' + number + '))?\\)';
  var hsla = 'hsl[a]?\\((' + number + ')\\s*,\\s*(' + number + '[%])\\s*,\\s*(' + number + '[%])(?:\\s*,\\s*(' + number + '))?\\)';
  var hslaNoBackRefs = 'hsl[a]?\\((?:' + number + ')\\s*,\\s*(?:' + number + '[%])\\s*,\\s*(?:' + number + '[%])(?:\\s*,\\s*(?:' + number + '))?\\)';
  var hex3 = '\\#[0-9a-fA-F]{3}';
  var hex6 = '\\#[0-9a-fA-F]{6}';

  var ascending = function ascending(a, b) {
    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  };
  var descending = function descending(a, b) {
    return -1 * ascending(a, b);
  };

  var extend = Object.assign != null ? Object.assign.bind(Object) : function (tgt) {
    var args = arguments;
    for (var i = 1; i < args.length; i++) {
      var obj = args[i];
      if (obj == null) {
        continue;
      }
      var keys = Object.keys(obj);
      for (var j = 0; j < keys.length; j++) {
        var k = keys[j];
        tgt[k] = obj[k];
      }
    }
    return tgt;
  };

  // get [r, g, b] from #abc or #aabbcc
  var hex2tuple = function hex2tuple(hex) {
    if (!(hex.length === 4 || hex.length === 7) || hex[0] !== '#') {
      return;
    }
    var shortHex = hex.length === 4;
    var r, g, b;
    var base = 16;
    if (shortHex) {
      r = parseInt(hex[1] + hex[1], base);
      g = parseInt(hex[2] + hex[2], base);
      b = parseInt(hex[3] + hex[3], base);
    } else {
      r = parseInt(hex[1] + hex[2], base);
      g = parseInt(hex[3] + hex[4], base);
      b = parseInt(hex[5] + hex[6], base);
    }
    return [r, g, b];
  };

  // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0)
  var hsl2tuple = function hsl2tuple(hsl) {
    var ret;
    var h, s, l, a, r, g, b;
    function hue2rgb(p, q, t) {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }
    var m = new RegExp('^' + hsla + '$').exec(hsl);
    if (m) {
      // get hue
      h = parseInt(m[1]);
      if (h < 0) {
        h = (360 - -1 * h % 360) % 360;
      } else if (h > 360) {
        h = h % 360;
      }
      h /= 360; // normalise on [0, 1]

      s = parseFloat(m[2]);
      if (s < 0 || s > 100) {
        return;
      } // saturation is [0, 100]
      s = s / 100; // normalise on [0, 1]

      l = parseFloat(m[3]);
      if (l < 0 || l > 100) {
        return;
      } // lightness is [0, 100]
      l = l / 100; // normalise on [0, 1]

      a = m[4];
      if (a !== undefined) {
        a = parseFloat(a);
        if (a < 0 || a > 1) {
          return;
        } // alpha is [0, 1]
      }

      // now, convert to rgb
      // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
      if (s === 0) {
        r = g = b = Math.round(l * 255); // achromatic
      } else {
        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = Math.round(255 * hue2rgb(p, q, h + 1 / 3));
        g = Math.round(255 * hue2rgb(p, q, h));
        b = Math.round(255 * hue2rgb(p, q, h - 1 / 3));
      }
      ret = [r, g, b, a];
    }
    return ret;
  };

  // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0)
  var rgb2tuple = function rgb2tuple(rgb) {
    var ret;
    var m = new RegExp('^' + rgba + '$').exec(rgb);
    if (m) {
      ret = [];
      var isPct = [];
      for (var i = 1; i <= 3; i++) {
        var channel = m[i];
        if (channel[channel.length - 1] === '%') {
          isPct[i] = true;
        }
        channel = parseFloat(channel);
        if (isPct[i]) {
          channel = channel / 100 * 255; // normalise to [0, 255]
        }

        if (channel < 0 || channel > 255) {
          return;
        } // invalid channel value

        ret.push(Math.floor(channel));
      }
      var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];
      var allArePct = isPct[1] && isPct[2] && isPct[3];
      if (atLeastOneIsPct && !allArePct) {
        return;
      } // must all be percent values if one is

      var alpha = m[4];
      if (alpha !== undefined) {
        alpha = parseFloat(alpha);
        if (alpha < 0 || alpha > 1) {
          return;
        } // invalid alpha value

        ret.push(alpha);
      }
    }
    return ret;
  };
  var colorname2tuple = function colorname2tuple(color) {
    return colors[color.toLowerCase()];
  };
  var color2tuple = function color2tuple(color) {
    return (array(color) ? color : null) || colorname2tuple(color) || hex2tuple(color) || rgb2tuple(color) || hsl2tuple(color);
  };
  var colors = {
    // special colour names
    transparent: [0, 0, 0, 0],
    // NB alpha === 0

    // regular colours
    aliceblue: [240, 248, 255],
    antiquewhite: [250, 235, 215],
    aqua: [0, 255, 255],
    aquamarine: [127, 255, 212],
    azure: [240, 255, 255],
    beige: [245, 245, 220],
    bisque: [255, 228, 196],
    black: [0, 0, 0],
    blanchedalmond: [255, 235, 205],
    blue: [0, 0, 255],
    blueviolet: [138, 43, 226],
    brown: [165, 42, 42],
    burlywood: [222, 184, 135],
    cadetblue: [95, 158, 160],
    chartreuse: [127, 255, 0],
    chocolate: [210, 105, 30],
    coral: [255, 127, 80],
    cornflowerblue: [100, 149, 237],
    cornsilk: [255, 248, 220],
    crimson: [220, 20, 60],
    cyan: [0, 255, 255],
    darkblue: [0, 0, 139],
    darkcyan: [0, 139, 139],
    darkgoldenrod: [184, 134, 11],
    darkgray: [169, 169, 169],
    darkgreen: [0, 100, 0],
    darkgrey: [169, 169, 169],
    darkkhaki: [189, 183, 107],
    darkmagenta: [139, 0, 139],
    darkolivegreen: [85, 107, 47],
    darkorange: [255, 140, 0],
    darkorchid: [153, 50, 204],
    darkred: [139, 0, 0],
    darksalmon: [233, 150, 122],
    darkseagreen: [143, 188, 143],
    darkslateblue: [72, 61, 139],
    darkslategray: [47, 79, 79],
    darkslategrey: [47, 79, 79],
    darkturquoise: [0, 206, 209],
    darkviolet: [148, 0, 211],
    deeppink: [255, 20, 147],
    deepskyblue: [0, 191, 255],
    dimgray: [105, 105, 105],
    dimgrey: [105, 105, 105],
    dodgerblue: [30, 144, 255],
    firebrick: [178, 34, 34],
    floralwhite: [255, 250, 240],
    forestgreen: [34, 139, 34],
    fuchsia: [255, 0, 255],
    gainsboro: [220, 220, 220],
    ghostwhite: [248, 248, 255],
    gold: [255, 215, 0],
    goldenrod: [218, 165, 32],
    gray: [128, 128, 128],
    grey: [128, 128, 128],
    green: [0, 128, 0],
    greenyellow: [173, 255, 47],
    honeydew: [240, 255, 240],
    hotpink: [255, 105, 180],
    indianred: [205, 92, 92],
    indigo: [75, 0, 130],
    ivory: [255, 255, 240],
    khaki: [240, 230, 140],
    lavender: [230, 230, 250],
    lavenderblush: [255, 240, 245],
    lawngreen: [124, 252, 0],
    lemonchiffon: [255, 250, 205],
    lightblue: [173, 216, 230],
    lightcoral: [240, 128, 128],
    lightcyan: [224, 255, 255],
    lightgoldenrodyellow: [250, 250, 210],
    lightgray: [211, 211, 211],
    lightgreen: [144, 238, 144],
    lightgrey: [211, 211, 211],
    lightpink: [255, 182, 193],
    lightsalmon: [255, 160, 122],
    lightseagreen: [32, 178, 170],
    lightskyblue: [135, 206, 250],
    lightslategray: [119, 136, 153],
    lightslategrey: [119, 136, 153],
    lightsteelblue: [176, 196, 222],
    lightyellow: [255, 255, 224],
    lime: [0, 255, 0],
    limegreen: [50, 205, 50],
    linen: [250, 240, 230],
    magenta: [255, 0, 255],
    maroon: [128, 0, 0],
    mediumaquamarine: [102, 205, 170],
    mediumblue: [0, 0, 205],
    mediumorchid: [186, 85, 211],
    mediumpurple: [147, 112, 219],
    mediumseagreen: [60, 179, 113],
    mediumslateblue: [123, 104, 238],
    mediumspringgreen: [0, 250, 154],
    mediumturquoise: [72, 209, 204],
    mediumvioletred: [199, 21, 133],
    midnightblue: [25, 25, 112],
    mintcream: [245, 255, 250],
    mistyrose: [255, 228, 225],
    moccasin: [255, 228, 181],
    navajowhite: [255, 222, 173],
    navy: [0, 0, 128],
    oldlace: [253, 245, 230],
    olive: [128, 128, 0],
    olivedrab: [107, 142, 35],
    orange: [255, 165, 0],
    orangered: [255, 69, 0],
    orchid: [218, 112, 214],
    palegoldenrod: [238, 232, 170],
    palegreen: [152, 251, 152],
    paleturquoise: [175, 238, 238],
    palevioletred: [219, 112, 147],
    papayawhip: [255, 239, 213],
    peachpuff: [255, 218, 185],
    peru: [205, 133, 63],
    pink: [255, 192, 203],
    plum: [221, 160, 221],
    powderblue: [176, 224, 230],
    purple: [128, 0, 128],
    red: [255, 0, 0],
    rosybrown: [188, 143, 143],
    royalblue: [65, 105, 225],
    saddlebrown: [139, 69, 19],
    salmon: [250, 128, 114],
    sandybrown: [244, 164, 96],
    seagreen: [46, 139, 87],
    seashell: [255, 245, 238],
    sienna: [160, 82, 45],
    silver: [192, 192, 192],
    skyblue: [135, 206, 235],
    slateblue: [106, 90, 205],
    slategray: [112, 128, 144],
    slategrey: [112, 128, 144],
    snow: [255, 250, 250],
    springgreen: [0, 255, 127],
    steelblue: [70, 130, 180],
    tan: [210, 180, 140],
    teal: [0, 128, 128],
    thistle: [216, 191, 216],
    tomato: [255, 99, 71],
    turquoise: [64, 224, 208],
    violet: [238, 130, 238],
    wheat: [245, 222, 179],
    white: [255, 255, 255],
    whitesmoke: [245, 245, 245],
    yellow: [255, 255, 0],
    yellowgreen: [154, 205, 50]
  };

  // sets the value in a map (map may not be built)
  var setMap = function setMap(options) {
    var obj = options.map;
    var keys = options.keys;
    var l = keys.length;
    for (var i = 0; i < l; i++) {
      var key = keys[i];
      if (plainObject(key)) {
        throw Error('Tried to set map with object key');
      }
      if (i < keys.length - 1) {
        // extend the map if necessary
        if (obj[key] == null) {
          obj[key] = {};
        }
        obj = obj[key];
      } else {
        // set the value
        obj[key] = options.value;
      }
    }
  };

  // gets the value in a map even if it's not built in places
  var getMap = function getMap(options) {
    var obj = options.map;
    var keys = options.keys;
    var l = keys.length;
    for (var i = 0; i < l; i++) {
      var key = keys[i];
      if (plainObject(key)) {
        throw Error('Tried to get map with object key');
      }
      obj = obj[key];
      if (obj == null) {
        return obj;
      }
    }
    return obj;
  };

  /**
   * Checks if `value` is the
   * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
   * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an object, else `false`.
   * @example
   *
   * _.isObject({});
   * // => true
   *
   * _.isObject([1, 2, 3]);
   * // => true
   *
   * _.isObject(_.noop);
   * // => true
   *
   * _.isObject(null);
   * // => false
   */
  function isObject(value) {
    var type = typeof value;
    return value != null && (type == 'object' || type == 'function');
  }

  var isObject_1 = isObject;

  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

  function createCommonjsModule(fn, module) {
  	return module = { exports: {} }, fn(module, module.exports), module.exports;
  }

  /** Detect free variable `global` from Node.js. */
  var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

  var _freeGlobal = freeGlobal;

  /** Detect free variable `self`. */
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

  /** Used as a reference to the global object. */
  var root = _freeGlobal || freeSelf || Function('return this')();

  var _root = root;

  /**
   * Gets the timestamp of the number of milliseconds that have elapsed since
   * the Unix epoch (1 January 1970 00:00:00 UTC).
   *
   * @static
   * @memberOf _
   * @since 2.4.0
   * @category Date
   * @returns {number} Returns the timestamp.
   * @example
   *
   * _.defer(function(stamp) {
   *   console.log(_.now() - stamp);
   * }, _.now());
   * // => Logs the number of milliseconds it took for the deferred invocation.
   */
  var now = function() {
    return _root.Date.now();
  };

  var now_1 = now;

  /** Used to match a single whitespace character. */
  var reWhitespace = /\s/;

  /**
   * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
   * character of `string`.
   *
   * @private
   * @param {string} string The string to inspect.
   * @returns {number} Returns the index of the last non-whitespace character.
   */
  function trimmedEndIndex(string) {
    var index = string.length;

    while (index-- && reWhitespace.test(string.charAt(index))) {}
    return index;
  }

  var _trimmedEndIndex = trimmedEndIndex;

  /** Used to match leading whitespace. */
  var reTrimStart = /^\s+/;

  /**
   * The base implementation of `_.trim`.
   *
   * @private
   * @param {string} string The string to trim.
   * @returns {string} Returns the trimmed string.
   */
  function baseTrim(string) {
    return string
      ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
      : string;
  }

  var _baseTrim = baseTrim;

  /** Built-in value references. */
  var Symbol$1 = _root.Symbol;

  var _Symbol = Symbol$1;

  /** Used for built-in method references. */
  var objectProto$5 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$4 = objectProto$5.hasOwnProperty;

  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var nativeObjectToString$1 = objectProto$5.toString;

  /** Built-in value references. */
  var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;

  /**
   * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
   *
   * @private
   * @param {*} value The value to query.
   * @returns {string} Returns the raw `toStringTag`.
   */
  function getRawTag(value) {
    var isOwn = hasOwnProperty$4.call(value, symToStringTag$1),
        tag = value[symToStringTag$1];

    try {
      value[symToStringTag$1] = undefined;
      var unmasked = true;
    } catch (e) {}

    var result = nativeObjectToString$1.call(value);
    if (unmasked) {
      if (isOwn) {
        value[symToStringTag$1] = tag;
      } else {
        delete value[symToStringTag$1];
      }
    }
    return result;
  }

  var _getRawTag = getRawTag;

  /** Used for built-in method references. */
  var objectProto$4 = Object.prototype;

  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var nativeObjectToString = objectProto$4.toString;

  /**
   * Converts `value` to a string using `Object.prototype.toString`.
   *
   * @private
   * @param {*} value The value to convert.
   * @returns {string} Returns the converted string.
   */
  function objectToString(value) {
    return nativeObjectToString.call(value);
  }

  var _objectToString = objectToString;

  /** `Object#toString` result references. */
  var nullTag = '[object Null]',
      undefinedTag = '[object Undefined]';

  /** Built-in value references. */
  var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;

  /**
   * The base implementation of `getTag` without fallbacks for buggy environments.
   *
   * @private
   * @param {*} value The value to query.
   * @returns {string} Returns the `toStringTag`.
   */
  function baseGetTag(value) {
    if (value == null) {
      return value === undefined ? undefinedTag : nullTag;
    }
    return (symToStringTag && symToStringTag in Object(value))
      ? _getRawTag(value)
      : _objectToString(value);
  }

  var _baseGetTag = baseGetTag;

  /**
   * Checks if `value` is object-like. A value is object-like if it's not `null`
   * and has a `typeof` result of "object".
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
   * @example
   *
   * _.isObjectLike({});
   * // => true
   *
   * _.isObjectLike([1, 2, 3]);
   * // => true
   *
   * _.isObjectLike(_.noop);
   * // => false
   *
   * _.isObjectLike(null);
   * // => false
   */
  function isObjectLike(value) {
    return value != null && typeof value == 'object';
  }

  var isObjectLike_1 = isObjectLike;

  /** `Object#toString` result references. */
  var symbolTag = '[object Symbol]';

  /**
   * Checks if `value` is classified as a `Symbol` primitive or object.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
   * @example
   *
   * _.isSymbol(Symbol.iterator);
   * // => true
   *
   * _.isSymbol('abc');
   * // => false
   */
  function isSymbol(value) {
    return typeof value == 'symbol' ||
      (isObjectLike_1(value) && _baseGetTag(value) == symbolTag);
  }

  var isSymbol_1 = isSymbol;

  /** Used as references for various `Number` constants. */
  var NAN = 0 / 0;

  /** Used to detect bad signed hexadecimal string values. */
  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

  /** Used to detect binary string values. */
  var reIsBinary = /^0b[01]+$/i;

  /** Used to detect octal string values. */
  var reIsOctal = /^0o[0-7]+$/i;

  /** Built-in method references without a dependency on `root`. */
  var freeParseInt = parseInt;

  /**
   * Converts `value` to a number.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to process.
   * @returns {number} Returns the number.
   * @example
   *
   * _.toNumber(3.2);
   * // => 3.2
   *
   * _.toNumber(Number.MIN_VALUE);
   * // => 5e-324
   *
   * _.toNumber(Infinity);
   * // => Infinity
   *
   * _.toNumber('3.2');
   * // => 3.2
   */
  function toNumber(value) {
    if (typeof value == 'number') {
      return value;
    }
    if (isSymbol_1(value)) {
      return NAN;
    }
    if (isObject_1(value)) {
      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
      value = isObject_1(other) ? (other + '') : other;
    }
    if (typeof value != 'string') {
      return value === 0 ? value : +value;
    }
    value = _baseTrim(value);
    var isBinary = reIsBinary.test(value);
    return (isBinary || reIsOctal.test(value))
      ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
      : (reIsBadHex.test(value) ? NAN : +value);
  }

  var toNumber_1 = toNumber;

  /** Error message constants. */
  var FUNC_ERROR_TEXT$1 = 'Expected a function';

  /* Built-in method references for those with the same name as other `lodash` methods. */
  var nativeMax = Math.max,
      nativeMin = Math.min;

  /**
   * Creates a debounced function that delays invoking `func` until after `wait`
   * milliseconds have elapsed since the last time the debounced function was
   * invoked. The debounced function comes with a `cancel` method to cancel
   * delayed `func` invocations and a `flush` method to immediately invoke them.
   * Provide `options` to indicate whether `func` should be invoked on the
   * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
   * with the last arguments provided to the debounced function. Subsequent
   * calls to the debounced function return the result of the last `func`
   * invocation.
   *
   * **Note:** If `leading` and `trailing` options are `true`, `func` is
   * invoked on the trailing edge of the timeout only if the debounced function
   * is invoked more than once during the `wait` timeout.
   *
   * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
   * until to the next tick, similar to `setTimeout` with a timeout of `0`.
   *
   * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
   * for details over the differences between `_.debounce` and `_.throttle`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to debounce.
   * @param {number} [wait=0] The number of milliseconds to delay.
   * @param {Object} [options={}] The options object.
   * @param {boolean} [options.leading=false]
   *  Specify invoking on the leading edge of the timeout.
   * @param {number} [options.maxWait]
   *  The maximum time `func` is allowed to be delayed before it's invoked.
   * @param {boolean} [options.trailing=true]
   *  Specify invoking on the trailing edge of the timeout.
   * @returns {Function} Returns the new debounced function.
   * @example
   *
   * // Avoid costly calculations while the window size is in flux.
   * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
   *
   * // Invoke `sendMail` when clicked, debouncing subsequent calls.
   * jQuery(element).on('click', _.debounce(sendMail, 300, {
   *   'leading': true,
   *   'trailing': false
   * }));
   *
   * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
   * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
   * var source = new EventSource('/stream');
   * jQuery(source).on('message', debounced);
   *
   * // Cancel the trailing debounced invocation.
   * jQuery(window).on('popstate', debounced.cancel);
   */
  function debounce(func, wait, options) {
    var lastArgs,
        lastThis,
        maxWait,
        result,
        timerId,
        lastCallTime,
        lastInvokeTime = 0,
        leading = false,
        maxing = false,
        trailing = true;

    if (typeof func != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT$1);
    }
    wait = toNumber_1(wait) || 0;
    if (isObject_1(options)) {
      leading = !!options.leading;
      maxing = 'maxWait' in options;
      maxWait = maxing ? nativeMax(toNumber_1(options.maxWait) || 0, wait) : maxWait;
      trailing = 'trailing' in options ? !!options.trailing : trailing;
    }

    function invokeFunc(time) {
      var args = lastArgs,
          thisArg = lastThis;

      lastArgs = lastThis = undefined;
      lastInvokeTime = time;
      result = func.apply(thisArg, args);
      return result;
    }

    function leadingEdge(time) {
      // Reset any `maxWait` timer.
      lastInvokeTime = time;
      // Start the timer for the trailing edge.
      timerId = setTimeout(timerExpired, wait);
      // Invoke the leading edge.
      return leading ? invokeFunc(time) : result;
    }

    function remainingWait(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime,
          timeWaiting = wait - timeSinceLastCall;

      return maxing
        ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
        : timeWaiting;
    }

    function shouldInvoke(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime;

      // Either this is the first call, activity has stopped and we're at the
      // trailing edge, the system time has gone backwards and we're treating
      // it as the trailing edge, or we've hit the `maxWait` limit.
      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
    }

    function timerExpired() {
      var time = now_1();
      if (shouldInvoke(time)) {
        return trailingEdge(time);
      }
      // Restart the timer.
      timerId = setTimeout(timerExpired, remainingWait(time));
    }

    function trailingEdge(time) {
      timerId = undefined;

      // Only invoke if we have `lastArgs` which means `func` has been
      // debounced at least once.
      if (trailing && lastArgs) {
        return invokeFunc(time);
      }
      lastArgs = lastThis = undefined;
      return result;
    }

    function cancel() {
      if (timerId !== undefined) {
        clearTimeout(timerId);
      }
      lastInvokeTime = 0;
      lastArgs = lastCallTime = lastThis = timerId = undefined;
    }

    function flush() {
      return timerId === undefined ? result : trailingEdge(now_1());
    }

    function debounced() {
      var time = now_1(),
          isInvoking = shouldInvoke(time);

      lastArgs = arguments;
      lastThis = this;
      lastCallTime = time;

      if (isInvoking) {
        if (timerId === undefined) {
          return leadingEdge(lastCallTime);
        }
        if (maxing) {
          // Handle invocations in a tight loop.
          clearTimeout(timerId);
          timerId = setTimeout(timerExpired, wait);
          return invokeFunc(lastCallTime);
        }
      }
      if (timerId === undefined) {
        timerId = setTimeout(timerExpired, wait);
      }
      return result;
    }
    debounced.cancel = cancel;
    debounced.flush = flush;
    return debounced;
  }

  var debounce_1 = debounce;

  var performance = _window ? _window.performance : null;
  var pnow = performance && performance.now ? function () {
    return performance.now();
  } : function () {
    return Date.now();
  };
  var raf = function () {
    if (_window) {
      if (_window.requestAnimationFrame) {
        return function (fn) {
          _window.requestAnimationFrame(fn);
        };
      } else if (_window.mozRequestAnimationFrame) {
        return function (fn) {
          _window.mozRequestAnimationFrame(fn);
        };
      } else if (_window.webkitRequestAnimationFrame) {
        return function (fn) {
          _window.webkitRequestAnimationFrame(fn);
        };
      } else if (_window.msRequestAnimationFrame) {
        return function (fn) {
          _window.msRequestAnimationFrame(fn);
        };
      }
    }
    return function (fn) {
      if (fn) {
        setTimeout(function () {
          fn(pnow());
        }, 1000 / 60);
      }
    };
  }();
  var requestAnimationFrame = function requestAnimationFrame(fn) {
    return raf(fn);
  };
  var performanceNow = pnow;

  var DEFAULT_HASH_SEED = 9261;
  var K = 65599; // 37 also works pretty well
  var DEFAULT_HASH_SEED_ALT = 5381;
  var hashIterableInts = function hashIterableInts(iterator) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;
    // sdbm/string-hash
    var hash = seed;
    var entry;
    for (;;) {
      entry = iterator.next();
      if (entry.done) {
        break;
      }
      hash = hash * K + entry.value | 0;
    }
    return hash;
  };
  var hashInt = function hashInt(num) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;
    // sdbm/string-hash
    return seed * K + num | 0;
  };
  var hashIntAlt = function hashIntAlt(num) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED_ALT;
    // djb2/string-hash
    return (seed << 5) + seed + num | 0;
  };
  var combineHashes = function combineHashes(hash1, hash2) {
    return hash1 * 0x200000 + hash2;
  };
  var combineHashesArray = function combineHashesArray(hashes) {
    return hashes[0] * 0x200000 + hashes[1];
  };
  var hashArrays = function hashArrays(hashes1, hashes2) {
    return [hashInt(hashes1[0], hashes2[0]), hashIntAlt(hashes1[1], hashes2[1])];
  };
  var hashIntsArray = function hashIntsArray(ints, seed) {
    var entry = {
      value: 0,
      done: false
    };
    var i = 0;
    var length = ints.length;
    var iterator = {
      next: function next() {
        if (i < length) {
          entry.value = ints[i++];
        } else {
          entry.done = true;
        }
        return entry;
      }
    };
    return hashIterableInts(iterator, seed);
  };
  var hashString = function hashString(str, seed) {
    var entry = {
      value: 0,
      done: false
    };
    var i = 0;
    var length = str.length;
    var iterator = {
      next: function next() {
        if (i < length) {
          entry.value = str.charCodeAt(i++);
        } else {
          entry.done = true;
        }
        return entry;
      }
    };
    return hashIterableInts(iterator, seed);
  };
  var hashStrings = function hashStrings() {
    return hashStringsArray(arguments);
  };
  var hashStringsArray = function hashStringsArray(strs) {
    var hash;
    for (var i = 0; i < strs.length; i++) {
      var str = strs[i];
      if (i === 0) {
        hash = hashString(str);
      } else {
        hash = hashString(str, hash);
      }
    }
    return hash;
  };

  /*global console */
  var warningsEnabled = true;
  var warnSupported = console.warn != null; // eslint-disable-line no-console
  var traceSupported = console.trace != null; // eslint-disable-line no-console

  var MAX_INT$1 = Number.MAX_SAFE_INTEGER || 9007199254740991;
  var trueify = function trueify() {
    return true;
  };
  var falsify = function falsify() {
    return false;
  };
  var zeroify = function zeroify() {
    return 0;
  };
  var noop$1 = function noop() {};
  var error = function error(msg) {
    throw new Error(msg);
  };
  var warnings = function warnings(enabled) {
    if (enabled !== undefined) {
      warningsEnabled = !!enabled;
    } else {
      return warningsEnabled;
    }
  };
  var warn = function warn(msg) {
    /* eslint-disable no-console */
    if (!warnings()) {
      return;
    }
    if (warnSupported) {
      console.warn(msg);
    } else {
      console.log(msg);
      if (traceSupported) {
        console.trace();
      }
    }
  }; /* eslint-enable */

  var clone = function clone(obj) {
    return extend({}, obj);
  };

  // gets a shallow copy of the argument
  var copy = function copy(obj) {
    if (obj == null) {
      return obj;
    }
    if (array(obj)) {
      return obj.slice();
    } else if (plainObject(obj)) {
      return clone(obj);
    } else {
      return obj;
    }
  };
  var copyArray$1 = function copyArray(arr) {
    return arr.slice();
  };
  var uuid = function uuid(a, b /* placeholders */) {
    for (
    // loop :)
    b = a = '';
    // b - result , a - numeric letiable
    a++ < 36;
    //
    b += a * 51 & 52 // if "a" is not 9 or 14 or 19 or 24
    ?
    //  return a random number or 4
    (a ^ 15 // if "a" is not 15
    ?
    // generate a random number from 0 to 15
    8 ^ Math.random() * (a ^ 20 ? 16 : 4) // unless "a" is 20, in which case a random number from 8 to 11
    : 4 //  otherwise 4
    ).toString(16) : '-' //  in other cases (if "a" is 9,14,19,24) insert "-"
    ) {
    }
    return b;
  };
  var _staticEmptyObject = {};
  var staticEmptyObject = function staticEmptyObject() {
    return _staticEmptyObject;
  };
  var defaults$g = function defaults(_defaults) {
    var keys = Object.keys(_defaults);
    return function (opts) {
      var filledOpts = {};
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var optVal = opts == null ? undefined : opts[key];
        filledOpts[key] = optVal === undefined ? _defaults[key] : optVal;
      }
      return filledOpts;
    };
  };
  var removeFromArray = function removeFromArray(arr, ele, oneCopy) {
    for (var i = arr.length - 1; i >= 0; i--) {
      if (arr[i] === ele) {
        arr.splice(i, 1);
        if (oneCopy) {
          break;
        }
      }
    }
  };
  var clearArray = function clearArray(arr) {
    arr.splice(0, arr.length);
  };
  var push = function push(arr, otherArr) {
    for (var i = 0; i < otherArr.length; i++) {
      var el = otherArr[i];
      arr.push(el);
    }
  };
  var getPrefixedProperty = function getPrefixedProperty(obj, propName, prefix) {
    if (prefix) {
      propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth
    }

    return obj[propName];
  };
  var setPrefixedProperty = function setPrefixedProperty(obj, propName, prefix, value) {
    if (prefix) {
      propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth
    }

    obj[propName] = value;
  };

  /* global Map */
  var ObjectMap = /*#__PURE__*/function () {
    function ObjectMap() {
      _classCallCheck(this, ObjectMap);
      this._obj = {};
    }
    _createClass(ObjectMap, [{
      key: "set",
      value: function set(key, val) {
        this._obj[key] = val;
        return this;
      }
    }, {
      key: "delete",
      value: function _delete(key) {
        this._obj[key] = undefined;
        return this;
      }
    }, {
      key: "clear",
      value: function clear() {
        this._obj = {};
      }
    }, {
      key: "has",
      value: function has(key) {
        return this._obj[key] !== undefined;
      }
    }, {
      key: "get",
      value: function get(key) {
        return this._obj[key];
      }
    }]);
    return ObjectMap;
  }();
  var Map$2 = typeof Map !== 'undefined' ? Map : ObjectMap;

  /* global Set */

  var undef = "undefined" ;
  var ObjectSet = /*#__PURE__*/function () {
    function ObjectSet(arrayOrObjectSet) {
      _classCallCheck(this, ObjectSet);
      this._obj = Object.create(null);
      this.size = 0;
      if (arrayOrObjectSet != null) {
        var arr;
        if (arrayOrObjectSet.instanceString != null && arrayOrObjectSet.instanceString() === this.instanceString()) {
          arr = arrayOrObjectSet.toArray();
        } else {
          arr = arrayOrObjectSet;
        }
        for (var i = 0; i < arr.length; i++) {
          this.add(arr[i]);
        }
      }
    }
    _createClass(ObjectSet, [{
      key: "instanceString",
      value: function instanceString() {
        return 'set';
      }
    }, {
      key: "add",
      value: function add(val) {
        var o = this._obj;
        if (o[val] !== 1) {
          o[val] = 1;
          this.size++;
        }
      }
    }, {
      key: "delete",
      value: function _delete(val) {
        var o = this._obj;
        if (o[val] === 1) {
          o[val] = 0;
          this.size--;
        }
      }
    }, {
      key: "clear",
      value: function clear() {
        this._obj = Object.create(null);
      }
    }, {
      key: "has",
      value: function has(val) {
        return this._obj[val] === 1;
      }
    }, {
      key: "toArray",
      value: function toArray() {
        var _this = this;
        return Object.keys(this._obj).filter(function (key) {
          return _this.has(key);
        });
      }
    }, {
      key: "forEach",
      value: function forEach(callback, thisArg) {
        return this.toArray().forEach(callback, thisArg);
      }
    }]);
    return ObjectSet;
  }();
  var Set$1 = (typeof Set === "undefined" ? "undefined" : _typeof(Set)) !== undef ? Set : ObjectSet;

  // represents a node or an edge
  var Element = function Element(cy, params) {
    var restore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    if (cy === undefined || params === undefined || !core(cy)) {
      error('An element must have a core reference and parameters set');
      return;
    }
    var group = params.group;

    // try to automatically infer the group if unspecified
    if (group == null) {
      if (params.data && params.data.source != null && params.data.target != null) {
        group = 'edges';
      } else {
        group = 'nodes';
      }
    }

    // validate group
    if (group !== 'nodes' && group !== 'edges') {
      error('An element must be of type `nodes` or `edges`; you specified `' + group + '`');
      return;
    }

    // make the element array-like, just like a collection
    this.length = 1;
    this[0] = this;

    // NOTE: when something is added here, add also to ele.json()
    var _p = this._private = {
      cy: cy,
      single: true,
      // indicates this is an element
      data: params.data || {},
      // data object
      position: params.position || {
        x: 0,
        y: 0
      },
      // (x, y) position pair
      autoWidth: undefined,
      // width and height of nodes calculated by the renderer when set to special 'auto' value
      autoHeight: undefined,
      autoPadding: undefined,
      compoundBoundsClean: false,
      // whether the compound dimensions need to be recalculated the next time dimensions are read
      listeners: [],
      // array of bound listeners
      group: group,
      // string; 'nodes' or 'edges'
      style: {},
      // properties as set by the style
      rstyle: {},
      // properties for style sent from the renderer to the core
      styleCxts: [],
      // applied style contexts from the styler
      styleKeys: {},
      // per-group keys of style property values
      removed: true,
      // whether it's inside the vis; true if removed (set true here since we call restore)
      selected: params.selected ? true : false,
      // whether it's selected
      selectable: params.selectable === undefined ? true : params.selectable ? true : false,
      // whether it's selectable
      locked: params.locked ? true : false,
      // whether the element is locked (cannot be moved)
      grabbed: false,
      // whether the element is grabbed by the mouse; renderer sets this privately
      grabbable: params.grabbable === undefined ? true : params.grabbable ? true : false,
      // whether the element can be grabbed
      pannable: params.pannable === undefined ? group === 'edges' ? true : false : params.pannable ? true : false,
      // whether the element has passthrough panning enabled
      active: false,
      // whether the element is active from user interaction
      classes: new Set$1(),
      // map ( className => true )
      animation: {
        // object for currently-running animations
        current: [],
        queue: []
      },
      rscratch: {},
      // object in which the renderer can store information
      scratch: params.scratch || {},
      // scratch objects
      edges: [],
      // array of connected edges
      children: [],
      // array of children
      parent: params.parent && params.parent.isNode() ? params.parent : null,
      // parent ref
      traversalCache: {},
      // cache of output of traversal functions
      backgrounding: false,
      // whether background images are loading
      bbCache: null,
      // cache of the current bounding box
      bbCacheShift: {
        x: 0,
        y: 0
      },
      // shift applied to cached bb to be applied on next get
      bodyBounds: null,
      // bounds cache of element body, w/o overlay
      overlayBounds: null,
      // bounds cache of element body, including overlay
      labelBounds: {
        // bounds cache of labels
        all: null,
        source: null,
        target: null,
        main: null
      },
      arrowBounds: {
        // bounds cache of edge arrows
        source: null,
        target: null,
        'mid-source': null,
        'mid-target': null
      }
    };
    if (_p.position.x == null) {
      _p.position.x = 0;
    }
    if (_p.position.y == null) {
      _p.position.y = 0;
    }

    // renderedPosition overrides if specified
    if (params.renderedPosition) {
      var rpos = params.renderedPosition;
      var pan = cy.pan();
      var zoom = cy.zoom();
      _p.position = {
        x: (rpos.x - pan.x) / zoom,
        y: (rpos.y - pan.y) / zoom
      };
    }
    var classes = [];
    if (array(params.classes)) {
      classes = params.classes;
    } else if (string(params.classes)) {
      classes = params.classes.split(/\s+/);
    }
    for (var i = 0, l = classes.length; i < l; i++) {
      var cls = classes[i];
      if (!cls || cls === '') {
        continue;
      }
      _p.classes.add(cls);
    }
    this.createEmitter();
    var bypass = params.style || params.css;
    if (bypass) {
      warn('Setting a `style` bypass at element creation should be done only when absolutely necessary.  Try to use the stylesheet instead.');
      this.style(bypass);
    }
    if (restore === undefined || restore) {
      this.restore();
    }
  };

  var defineSearch = function defineSearch(params) {
    params = {
      bfs: params.bfs || !params.dfs,
      dfs: params.dfs || !params.bfs
    };

    // from pseudocode on wikipedia
    return function searchFn(roots, fn, directed) {
      var options;
      if (plainObject(roots) && !elementOrCollection(roots)) {
        options = roots;
        roots = options.roots || options.root;
        fn = options.visit;
        directed = options.directed;
      }
      directed = arguments.length === 2 && !fn$6(fn) ? fn : directed;
      fn = fn$6(fn) ? fn : function () {};
      var cy = this._private.cy;
      var v = roots = string(roots) ? this.filter(roots) : roots;
      var Q = [];
      var connectedNodes = [];
      var connectedBy = {};
      var id2depth = {};
      var V = {};
      var j = 0;
      var found;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;

      // enqueue v
      for (var i = 0; i < v.length; i++) {
        var vi = v[i];
        var viId = vi.id();
        if (vi.isNode()) {
          Q.unshift(vi);
          if (params.bfs) {
            V[viId] = true;
            connectedNodes.push(vi);
          }
          id2depth[viId] = 0;
        }
      }
      var _loop = function _loop() {
        var v = params.bfs ? Q.shift() : Q.pop();
        var vId = v.id();
        if (params.dfs) {
          if (V[vId]) {
            return "continue";
          }
          V[vId] = true;
          connectedNodes.push(v);
        }
        var depth = id2depth[vId];
        var prevEdge = connectedBy[vId];
        var src = prevEdge != null ? prevEdge.source() : null;
        var tgt = prevEdge != null ? prevEdge.target() : null;
        var prevNode = prevEdge == null ? undefined : v.same(src) ? tgt[0] : src[0];
        var ret = void 0;
        ret = fn(v, prevEdge, prevNode, j++, depth);
        if (ret === true) {
          found = v;
          return "break";
        }
        if (ret === false) {
          return "break";
        }
        var vwEdges = v.connectedEdges().filter(function (e) {
          return (!directed || e.source().same(v)) && edges.has(e);
        });
        for (var _i2 = 0; _i2 < vwEdges.length; _i2++) {
          var e = vwEdges[_i2];
          var w = e.connectedNodes().filter(function (n) {
            return !n.same(v) && nodes.has(n);
          });
          var wId = w.id();
          if (w.length !== 0 && !V[wId]) {
            w = w[0];
            Q.push(w);
            if (params.bfs) {
              V[wId] = true;
              connectedNodes.push(w);
            }
            connectedBy[wId] = e;
            id2depth[wId] = id2depth[vId] + 1;
          }
        }
      };
      while (Q.length !== 0) {
        var _ret = _loop();
        if (_ret === "continue") continue;
        if (_ret === "break") break;
      }
      var connectedEles = cy.collection();
      for (var _i = 0; _i < connectedNodes.length; _i++) {
        var node = connectedNodes[_i];
        var edge = connectedBy[node.id()];
        if (edge != null) {
          connectedEles.push(edge);
        }
        connectedEles.push(node);
      }
      return {
        path: cy.collection(connectedEles),
        found: cy.collection(found)
      };
    };
  };

  // search, spanning trees, etc
  var elesfn$v = {
    breadthFirstSearch: defineSearch({
      bfs: true
    }),
    depthFirstSearch: defineSearch({
      dfs: true
    })
  };

  // nice, short mathematical alias
  elesfn$v.bfs = elesfn$v.breadthFirstSearch;
  elesfn$v.dfs = elesfn$v.depthFirstSearch;

  var heap$1 = createCommonjsModule(function (module, exports) {
  // Generated by CoffeeScript 1.8.0
  (function() {
    var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;

    floor = Math.floor, min = Math.min;


    /*
    Default comparison function to be used
     */

    defaultCmp = function(x, y) {
      if (x < y) {
        return -1;
      }
      if (x > y) {
        return 1;
      }
      return 0;
    };


    /*
    Insert item x in list a, and keep it sorted assuming a is sorted.
    
    If x is already in a, insert it to the right of the rightmost x.
    
    Optional args lo (default 0) and hi (default a.length) bound the slice
    of a to be searched.
     */

    insort = function(a, x, lo, hi, cmp) {
      var mid;
      if (lo == null) {
        lo = 0;
      }
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (lo < 0) {
        throw new Error('lo must be non-negative');
      }
      if (hi == null) {
        hi = a.length;
      }
      while (lo < hi) {
        mid = floor((lo + hi) / 2);
        if (cmp(x, a[mid]) < 0) {
          hi = mid;
        } else {
          lo = mid + 1;
        }
      }
      return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);
    };


    /*
    Push item onto heap, maintaining the heap invariant.
     */

    heappush = function(array, item, cmp) {
      if (cmp == null) {
        cmp = defaultCmp;
      }
      array.push(item);
      return _siftdown(array, 0, array.length - 1, cmp);
    };


    /*
    Pop the smallest item off the heap, maintaining the heap invariant.
     */

    heappop = function(array, cmp) {
      var lastelt, returnitem;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      lastelt = array.pop();
      if (array.length) {
        returnitem = array[0];
        array[0] = lastelt;
        _siftup(array, 0, cmp);
      } else {
        returnitem = lastelt;
      }
      return returnitem;
    };


    /*
    Pop and return the current smallest value, and add the new item.
    
    This is more efficient than heappop() followed by heappush(), and can be
    more appropriate when using a fixed size heap. Note that the value
    returned may be larger than item! That constrains reasonable use of
    this routine unless written as part of a conditional replacement:
        if item > array[0]
          item = heapreplace(array, item)
     */

    heapreplace = function(array, item, cmp) {
      var returnitem;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      returnitem = array[0];
      array[0] = item;
      _siftup(array, 0, cmp);
      return returnitem;
    };


    /*
    Fast version of a heappush followed by a heappop.
     */

    heappushpop = function(array, item, cmp) {
      var _ref;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (array.length && cmp(array[0], item) < 0) {
        _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];
        _siftup(array, 0, cmp);
      }
      return item;
    };


    /*
    Transform list into a heap, in-place, in O(array.length) time.
     */

    heapify = function(array, cmp) {
      var i, _i, _len, _ref1, _results, _results1;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      _ref1 = (function() {
        _results1 = [];
        for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }
        return _results1;
      }).apply(this).reverse();
      _results = [];
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        i = _ref1[_i];
        _results.push(_siftup(array, i, cmp));
      }
      return _results;
    };


    /*
    Update the position of the given item in the heap.
    This function should be called every time the item is being modified.
     */

    updateItem = function(array, item, cmp) {
      var pos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      pos = array.indexOf(item);
      if (pos === -1) {
        return;
      }
      _siftdown(array, 0, pos, cmp);
      return _siftup(array, pos, cmp);
    };


    /*
    Find the n largest elements in a dataset.
     */

    nlargest = function(array, n, cmp) {
      var elem, result, _i, _len, _ref;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      result = array.slice(0, n);
      if (!result.length) {
        return result;
      }
      heapify(result, cmp);
      _ref = array.slice(n);
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        elem = _ref[_i];
        heappushpop(result, elem, cmp);
      }
      return result.sort(cmp).reverse();
    };


    /*
    Find the n smallest elements in a dataset.
     */

    nsmallest = function(array, n, cmp) {
      var elem, los, result, _i, _j, _len, _ref, _ref1, _results;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (n * 10 <= array.length) {
        result = array.slice(0, n).sort(cmp);
        if (!result.length) {
          return result;
        }
        los = result[result.length - 1];
        _ref = array.slice(n);
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          elem = _ref[_i];
          if (cmp(elem, los) < 0) {
            insort(result, elem, 0, null, cmp);
            result.pop();
            los = result[result.length - 1];
          }
        }
        return result;
      }
      heapify(array, cmp);
      _results = [];
      for (_j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; 0 <= _ref1 ? ++_j : --_j) {
        _results.push(heappop(array, cmp));
      }
      return _results;
    };

    _siftdown = function(array, startpos, pos, cmp) {
      var newitem, parent, parentpos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      newitem = array[pos];
      while (pos > startpos) {
        parentpos = (pos - 1) >> 1;
        parent = array[parentpos];
        if (cmp(newitem, parent) < 0) {
          array[pos] = parent;
          pos = parentpos;
          continue;
        }
        break;
      }
      return array[pos] = newitem;
    };

    _siftup = function(array, pos, cmp) {
      var childpos, endpos, newitem, rightpos, startpos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      endpos = array.length;
      startpos = pos;
      newitem = array[pos];
      childpos = 2 * pos + 1;
      while (childpos < endpos) {
        rightpos = childpos + 1;
        if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {
          childpos = rightpos;
        }
        array[pos] = array[childpos];
        pos = childpos;
        childpos = 2 * pos + 1;
      }
      array[pos] = newitem;
      return _siftdown(array, startpos, pos, cmp);
    };

    Heap = (function() {
      Heap.push = heappush;

      Heap.pop = heappop;

      Heap.replace = heapreplace;

      Heap.pushpop = heappushpop;

      Heap.heapify = heapify;

      Heap.updateItem = updateItem;

      Heap.nlargest = nlargest;

      Heap.nsmallest = nsmallest;

      function Heap(cmp) {
        this.cmp = cmp != null ? cmp : defaultCmp;
        this.nodes = [];
      }

      Heap.prototype.push = function(x) {
        return heappush(this.nodes, x, this.cmp);
      };

      Heap.prototype.pop = function() {
        return heappop(this.nodes, this.cmp);
      };

      Heap.prototype.peek = function() {
        return this.nodes[0];
      };

      Heap.prototype.contains = function(x) {
        return this.nodes.indexOf(x) !== -1;
      };

      Heap.prototype.replace = function(x) {
        return heapreplace(this.nodes, x, this.cmp);
      };

      Heap.prototype.pushpop = function(x) {
        return heappushpop(this.nodes, x, this.cmp);
      };

      Heap.prototype.heapify = function() {
        return heapify(this.nodes, this.cmp);
      };

      Heap.prototype.updateItem = function(x) {
        return updateItem(this.nodes, x, this.cmp);
      };

      Heap.prototype.clear = function() {
        return this.nodes = [];
      };

      Heap.prototype.empty = function() {
        return this.nodes.length === 0;
      };

      Heap.prototype.size = function() {
        return this.nodes.length;
      };

      Heap.prototype.clone = function() {
        var heap;
        heap = new Heap();
        heap.nodes = this.nodes.slice(0);
        return heap;
      };

      Heap.prototype.toArray = function() {
        return this.nodes.slice(0);
      };

      Heap.prototype.insert = Heap.prototype.push;

      Heap.prototype.top = Heap.prototype.peek;

      Heap.prototype.front = Heap.prototype.peek;

      Heap.prototype.has = Heap.prototype.contains;

      Heap.prototype.copy = Heap.prototype.clone;

      return Heap;

    })();

    (function(root, factory) {
      {
        return module.exports = factory();
      }
    })(this, function() {
      return Heap;
    });

  }).call(commonjsGlobal);
  });

  var heap = heap$1;

  var dijkstraDefaults = defaults$g({
    root: null,
    weight: function weight(edge) {
      return 1;
    },
    directed: false
  });
  var elesfn$u = {
    dijkstra: function dijkstra(options) {
      if (!plainObject(options)) {
        var args = arguments;
        options = {
          root: args[0],
          weight: args[1],
          directed: args[2]
        };
      }
      var _dijkstraDefaults = dijkstraDefaults(options),
        root = _dijkstraDefaults.root,
        weight = _dijkstraDefaults.weight,
        directed = _dijkstraDefaults.directed;
      var eles = this;
      var weightFn = weight;
      var source = string(root) ? this.filter(root)[0] : root[0];
      var dist = {};
      var prev = {};
      var knownDist = {};
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      edges.unmergeBy(function (ele) {
        return ele.isLoop();
      });
      var getDist = function getDist(node) {
        return dist[node.id()];
      };
      var setDist = function setDist(node, d) {
        dist[node.id()] = d;
        Q.updateItem(node);
      };
      var Q = new heap(function (a, b) {
        return getDist(a) - getDist(b);
      });
      for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        dist[node.id()] = node.same(source) ? 0 : Infinity;
        Q.push(node);
      }
      var distBetween = function distBetween(u, v) {
        var uvs = (directed ? u.edgesTo(v) : u.edgesWith(v)).intersect(edges);
        var smallestDistance = Infinity;
        var smallestEdge;
        for (var _i = 0; _i < uvs.length; _i++) {
          var edge = uvs[_i];
          var _weight = weightFn(edge);
          if (_weight < smallestDistance || !smallestEdge) {
            smallestDistance = _weight;
            smallestEdge = edge;
          }
        }
        return {
          edge: smallestEdge,
          dist: smallestDistance
        };
      };
      while (Q.size() > 0) {
        var u = Q.pop();
        var smalletsDist = getDist(u);
        var uid = u.id();
        knownDist[uid] = smalletsDist;
        if (smalletsDist === Infinity) {
          continue;
        }
        var neighbors = u.neighborhood().intersect(nodes);
        for (var _i2 = 0; _i2 < neighbors.length; _i2++) {
          var v = neighbors[_i2];
          var vid = v.id();
          var vDist = distBetween(u, v);
          var alt = smalletsDist + vDist.dist;
          if (alt < getDist(v)) {
            setDist(v, alt);
            prev[vid] = {
              node: u,
              edge: vDist.edge
            };
          }
        } // for
      } // while

      return {
        distanceTo: function distanceTo(node) {
          var target = string(node) ? nodes.filter(node)[0] : node[0];
          return knownDist[target.id()];
        },
        pathTo: function pathTo(node) {
          var target = string(node) ? nodes.filter(node)[0] : node[0];
          var S = [];
          var u = target;
          var uid = u.id();
          if (target.length > 0) {
            S.unshift(target);
            while (prev[uid]) {
              var p = prev[uid];
              S.unshift(p.edge);
              S.unshift(p.node);
              u = p.node;
              uid = u.id();
            }
          }
          return eles.spawn(S);
        }
      };
    }
  };

  var elesfn$t = {
    // kruskal's algorithm (finds min spanning tree, assuming undirected graph)
    // implemented from pseudocode from wikipedia
    kruskal: function kruskal(weightFn) {
      weightFn = weightFn || function (edge) {
        return 1;
      };
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var numNodes = nodes.length;
      var forest = new Array(numNodes);
      var A = nodes; // assumes byGroup() creates new collections that can be safely mutated

      var findSetIndex = function findSetIndex(ele) {
        for (var i = 0; i < forest.length; i++) {
          var eles = forest[i];
          if (eles.has(ele)) {
            return i;
          }
        }
      };

      // start with one forest per node
      for (var i = 0; i < numNodes; i++) {
        forest[i] = this.spawn(nodes[i]);
      }
      var S = edges.sort(function (a, b) {
        return weightFn(a) - weightFn(b);
      });
      for (var _i = 0; _i < S.length; _i++) {
        var edge = S[_i];
        var u = edge.source()[0];
        var v = edge.target()[0];
        var setUIndex = findSetIndex(u);
        var setVIndex = findSetIndex(v);
        var setU = forest[setUIndex];
        var setV = forest[setVIndex];
        if (setUIndex !== setVIndex) {
          A.merge(edge);

          // combine forests for u and v
          setU.merge(setV);
          forest.splice(setVIndex, 1);
        }
      }
      return A;
    }
  };

  var aStarDefaults = defaults$g({
    root: null,
    goal: null,
    weight: function weight(edge) {
      return 1;
    },
    heuristic: function heuristic(edge) {
      return 0;
    },
    directed: false
  });
  var elesfn$s = {
    // Implemented from pseudocode from wikipedia
    aStar: function aStar(options) {
      var cy = this.cy();
      var _aStarDefaults = aStarDefaults(options),
        root = _aStarDefaults.root,
        goal = _aStarDefaults.goal,
        heuristic = _aStarDefaults.heuristic,
        directed = _aStarDefaults.directed,
        weight = _aStarDefaults.weight;
      root = cy.collection(root)[0];
      goal = cy.collection(goal)[0];
      var sid = root.id();
      var tid = goal.id();
      var gScore = {};
      var fScore = {};
      var closedSetIds = {};
      var openSet = new heap(function (a, b) {
        return fScore[a.id()] - fScore[b.id()];
      });
      var openSetIds = new Set$1();
      var cameFrom = {};
      var cameFromEdge = {};
      var addToOpenSet = function addToOpenSet(ele, id) {
        openSet.push(ele);
        openSetIds.add(id);
      };
      var cMin, cMinId;
      var popFromOpenSet = function popFromOpenSet() {
        cMin = openSet.pop();
        cMinId = cMin.id();
        openSetIds["delete"](cMinId);
      };
      var isInOpenSet = function isInOpenSet(id) {
        return openSetIds.has(id);
      };
      addToOpenSet(root, sid);
      gScore[sid] = 0;
      fScore[sid] = heuristic(root);

      // Counter
      var steps = 0;

      // Main loop
      while (openSet.size() > 0) {
        popFromOpenSet();
        steps++;

        // If we've found our goal, then we are done
        if (cMinId === tid) {
          var path = [];
          var pathNode = goal;
          var pathNodeId = tid;
          var pathEdge = cameFromEdge[pathNodeId];
          for (;;) {
            path.unshift(pathNode);
            if (pathEdge != null) {
              path.unshift(pathEdge);
            }
            pathNode = cameFrom[pathNodeId];
            if (pathNode == null) {
              break;
            }
            pathNodeId = pathNode.id();
            pathEdge = cameFromEdge[pathNodeId];
          }
          return {
            found: true,
            distance: gScore[cMinId],
            path: this.spawn(path),
            steps: steps
          };
        }

        // Add cMin to processed nodes
        closedSetIds[cMinId] = true;

        // Update scores for neighbors of cMin
        // Take into account if graph is directed or not
        var vwEdges = cMin._private.edges;
        for (var i = 0; i < vwEdges.length; i++) {
          var e = vwEdges[i];

          // edge must be in set of calling eles
          if (!this.hasElementWithId(e.id())) {
            continue;
          }

          // cMin must be the source of edge if directed
          if (directed && e.data('source') !== cMinId) {
            continue;
          }
          var wSrc = e.source();
          var wTgt = e.target();
          var w = wSrc.id() !== cMinId ? wSrc : wTgt;
          var wid = w.id();

          // node must be in set of calling eles
          if (!this.hasElementWithId(wid)) {
            continue;
          }

          // if node is in closedSet, ignore it
          if (closedSetIds[wid]) {
            continue;
          }

          // New tentative score for node w
          var tempScore = gScore[cMinId] + weight(e);

          // Update gScore for node w if:
          //   w not present in openSet
          // OR
          //   tentative gScore is less than previous value

          // w not in openSet
          if (!isInOpenSet(wid)) {
            gScore[wid] = tempScore;
            fScore[wid] = tempScore + heuristic(w);
            addToOpenSet(w, wid);
            cameFrom[wid] = cMin;
            cameFromEdge[wid] = e;
            continue;
          }

          // w already in openSet, but with greater gScore
          if (tempScore < gScore[wid]) {
            gScore[wid] = tempScore;
            fScore[wid] = tempScore + heuristic(w);
            cameFrom[wid] = cMin;
            cameFromEdge[wid] = e;
          }
        } // End of neighbors update
      } // End of main loop

      // If we've reached here, then we've not reached our goal
      return {
        found: false,
        distance: undefined,
        path: undefined,
        steps: steps
      };
    }
  }; // elesfn

  var floydWarshallDefaults = defaults$g({
    weight: function weight(edge) {
      return 1;
    },
    directed: false
  });
  var elesfn$r = {
    // Implemented from pseudocode from wikipedia
    floydWarshall: function floydWarshall(options) {
      var cy = this.cy();
      var _floydWarshallDefault = floydWarshallDefaults(options),
        weight = _floydWarshallDefault.weight,
        directed = _floydWarshallDefault.directed;
      var weightFn = weight;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var N = nodes.length;
      var Nsq = N * N;
      var indexOf = function indexOf(node) {
        return nodes.indexOf(node);
      };
      var atIndex = function atIndex(i) {
        return nodes[i];
      };

      // Initialize distance matrix
      var dist = new Array(Nsq);
      for (var n = 0; n < Nsq; n++) {
        var j = n % N;
        var i = (n - j) / N;
        if (i === j) {
          dist[n] = 0;
        } else {
          dist[n] = Infinity;
        }
      }

      // Initialize matrix used for path reconstruction
      // Initialize distance matrix
      var next = new Array(Nsq);
      var edgeNext = new Array(Nsq);

      // Process edges
      for (var _i = 0; _i < edges.length; _i++) {
        var edge = edges[_i];
        var src = edge.source()[0];
        var tgt = edge.target()[0];
        if (src === tgt) {
          continue;
        } // exclude loops

        var s = indexOf(src);
        var t = indexOf(tgt);
        var st = s * N + t; // source to target index
        var _weight = weightFn(edge);

        // Check if already process another edge between same 2 nodes
        if (dist[st] > _weight) {
          dist[st] = _weight;
          next[st] = t;
          edgeNext[st] = edge;
        }

        // If undirected graph, process 'reversed' edge
        if (!directed) {
          var ts = t * N + s; // target to source index

          if (!directed && dist[ts] > _weight) {
            dist[ts] = _weight;
            next[ts] = s;
            edgeNext[ts] = edge;
          }
        }
      }

      // Main loop
      for (var k = 0; k < N; k++) {
        for (var _i2 = 0; _i2 < N; _i2++) {
          var ik = _i2 * N + k;
          for (var _j = 0; _j < N; _j++) {
            var ij = _i2 * N + _j;
            var kj = k * N + _j;
            if (dist[ik] + dist[kj] < dist[ij]) {
              dist[ij] = dist[ik] + dist[kj];
              next[ij] = next[ik];
            }
          }
        }
      }
      var getArgEle = function getArgEle(ele) {
        return (string(ele) ? cy.filter(ele) : ele)[0];
      };
      var indexOfArgEle = function indexOfArgEle(ele) {
        return indexOf(getArgEle(ele));
      };
      var res = {
        distance: function distance(from, to) {
          var i = indexOfArgEle(from);
          var j = indexOfArgEle(to);
          return dist[i * N + j];
        },
        path: function path(from, to) {
          var i = indexOfArgEle(from);
          var j = indexOfArgEle(to);
          var fromNode = atIndex(i);
          if (i === j) {
            return fromNode.collection();
          }
          if (next[i * N + j] == null) {
            return cy.collection();
          }
          var path = cy.collection();
          var prev = i;
          var edge;
          path.merge(fromNode);
          while (i !== j) {
            prev = i;
            i = next[i * N + j];
            edge = edgeNext[prev * N + i];
            path.merge(edge);
            path.merge(atIndex(i));
          }
          return path;
        }
      };
      return res;
    } // floydWarshall
  }; // elesfn

  var bellmanFordDefaults = defaults$g({
    weight: function weight(edge) {
      return 1;
    },
    directed: false,
    root: null
  });
  var elesfn$q = {
    // Implemented from pseudocode from wikipedia
    bellmanFord: function bellmanFord(options) {
      var _this = this;
      var _bellmanFordDefaults = bellmanFordDefaults(options),
        weight = _bellmanFordDefaults.weight,
        directed = _bellmanFordDefaults.directed,
        root = _bellmanFordDefaults.root;
      var weightFn = weight;
      var eles = this;
      var cy = this.cy();
      var _this$byGroup = this.byGroup(),
        edges = _this$byGroup.edges,
        nodes = _this$byGroup.nodes;
      var numNodes = nodes.length;
      var infoMap = new Map$2();
      var hasNegativeWeightCycle = false;
      var negativeWeightCycles = [];
      root = cy.collection(root)[0]; // in case selector passed

      edges.unmergeBy(function (edge) {
        return edge.isLoop();
      });
      var numEdges = edges.length;
      var getInfo = function getInfo(node) {
        var obj = infoMap.get(node.id());
        if (!obj) {
          obj = {};
          infoMap.set(node.id(), obj);
        }
        return obj;
      };
      var getNodeFromTo = function getNodeFromTo(to) {
        return (string(to) ? cy.$(to) : to)[0];
      };
      var distanceTo = function distanceTo(to) {
        return getInfo(getNodeFromTo(to)).dist;
      };
      var pathTo = function pathTo(to) {
        var thisStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : root;
        var end = getNodeFromTo(to);
        var path = [];
        var node = end;
        for (;;) {
          if (node == null) {
            return _this.spawn();
          }
          var _getInfo = getInfo(node),
            edge = _getInfo.edge,
            pred = _getInfo.pred;
          path.unshift(node[0]);
          if (node.same(thisStart) && path.length > 0) {
            break;
          }
          if (edge != null) {
            path.unshift(edge);
          }
          node = pred;
        }
        return eles.spawn(path);
      };

      // Initializations { dist, pred, edge }
      for (var i = 0; i < numNodes; i++) {
        var node = nodes[i];
        var info = getInfo(node);
        if (node.same(root)) {
          info.dist = 0;
        } else {
          info.dist = Infinity;
        }
        info.pred = null;
        info.edge = null;
      }

      // Edges relaxation
      var replacedEdge = false;
      var checkForEdgeReplacement = function checkForEdgeReplacement(node1, node2, edge, info1, info2, weight) {
        var dist = info1.dist + weight;
        if (dist < info2.dist && !edge.same(info1.edge)) {
          info2.dist = dist;
          info2.pred = node1;
          info2.edge = edge;
          replacedEdge = true;
        }
      };
      for (var _i = 1; _i < numNodes; _i++) {
        replacedEdge = false;
        for (var e = 0; e < numEdges; e++) {
          var edge = edges[e];
          var src = edge.source();
          var tgt = edge.target();
          var _weight = weightFn(edge);
          var srcInfo = getInfo(src);
          var tgtInfo = getInfo(tgt);
          checkForEdgeReplacement(src, tgt, edge, srcInfo, tgtInfo, _weight);

          // If undirected graph, we need to take into account the 'reverse' edge
          if (!directed) {
            checkForEdgeReplacement(tgt, src, edge, tgtInfo, srcInfo, _weight);
          }
        }
        if (!replacedEdge) {
          break;
        }
      }
      if (replacedEdge) {
        // Check for negative weight cycles
        var negativeWeightCycleIds = [];
        for (var _e = 0; _e < numEdges; _e++) {
          var _edge = edges[_e];
          var _src = _edge.source();
          var _tgt = _edge.target();
          var _weight2 = weightFn(_edge);
          var srcDist = getInfo(_src).dist;
          var tgtDist = getInfo(_tgt).dist;
          if (srcDist + _weight2 < tgtDist || !directed && tgtDist + _weight2 < srcDist) {
            if (!hasNegativeWeightCycle) {
              warn('Graph contains a negative weight cycle for Bellman-Ford');
              hasNegativeWeightCycle = true;
            }
            if (options.findNegativeWeightCycles !== false) {
              var negativeNodes = [];
              if (srcDist + _weight2 < tgtDist) {
                negativeNodes.push(_src);
              }
              if (!directed && tgtDist + _weight2 < srcDist) {
                negativeNodes.push(_tgt);
              }
              var numNegativeNodes = negativeNodes.length;
              for (var n = 0; n < numNegativeNodes; n++) {
                var start = negativeNodes[n];
                var cycle = [start];
                cycle.push(getInfo(start).edge);
                var _node = getInfo(start).pred;
                while (cycle.indexOf(_node) === -1) {
                  cycle.push(_node);
                  cycle.push(getInfo(_node).edge);
                  _node = getInfo(_node).pred;
                }
                cycle = cycle.slice(cycle.indexOf(_node));
                var smallestId = cycle[0].id();
                var smallestIndex = 0;
                for (var c = 2; c < cycle.length; c += 2) {
                  if (cycle[c].id() < smallestId) {
                    smallestId = cycle[c].id();
                    smallestIndex = c;
                  }
                }
                cycle = cycle.slice(smallestIndex).concat(cycle.slice(0, smallestIndex));
                cycle.push(cycle[0]);
                var cycleId = cycle.map(function (el) {
                  return el.id();
                }).join(",");
                if (negativeWeightCycleIds.indexOf(cycleId) === -1) {
                  negativeWeightCycles.push(eles.spawn(cycle));
                  negativeWeightCycleIds.push(cycleId);
                }
              }
            } else {
              break;
            }
          }
        }
      }
      return {
        distanceTo: distanceTo,
        pathTo: pathTo,
        hasNegativeWeightCycle: hasNegativeWeightCycle,
        negativeWeightCycles: negativeWeightCycles
      };
    } // bellmanFord
  }; // elesfn

  var sqrt2 = Math.sqrt(2);

  // Function which colapses 2 (meta) nodes into one
  // Updates the remaining edge lists
  // Receives as a paramater the edge which causes the collapse
  var collapse = function collapse(edgeIndex, nodeMap, remainingEdges) {
    if (remainingEdges.length === 0) {
      error("Karger-Stein must be run on a connected (sub)graph");
    }
    var edgeInfo = remainingEdges[edgeIndex];
    var sourceIn = edgeInfo[1];
    var targetIn = edgeInfo[2];
    var partition1 = nodeMap[sourceIn];
    var partition2 = nodeMap[targetIn];
    var newEdges = remainingEdges; // re-use array

    // Delete all edges between partition1 and partition2
    for (var i = newEdges.length - 1; i >= 0; i--) {
      var edge = newEdges[i];
      var src = edge[1];
      var tgt = edge[2];
      if (nodeMap[src] === partition1 && nodeMap[tgt] === partition2 || nodeMap[src] === partition2 && nodeMap[tgt] === partition1) {
        newEdges.splice(i, 1);
      }
    }

    // All edges pointing to partition2 should now point to partition1
    for (var _i = 0; _i < newEdges.length; _i++) {
      var _edge = newEdges[_i];
      if (_edge[1] === partition2) {
        // Check source
        newEdges[_i] = _edge.slice(); // copy
        newEdges[_i][1] = partition1;
      } else if (_edge[2] === partition2) {
        // Check target
        newEdges[_i] = _edge.slice(); // copy
        newEdges[_i][2] = partition1;
      }
    }

    // Move all nodes from partition2 to partition1
    for (var _i2 = 0; _i2 < nodeMap.length; _i2++) {
      if (nodeMap[_i2] === partition2) {
        nodeMap[_i2] = partition1;
      }
    }
    return newEdges;
  };

  // Contracts a graph until we reach a certain number of meta nodes
  var contractUntil = function contractUntil(metaNodeMap, remainingEdges, size, sizeLimit) {
    while (size > sizeLimit) {
      // Choose an edge randomly
      var edgeIndex = Math.floor(Math.random() * remainingEdges.length);

      // Collapse graph based on edge
      remainingEdges = collapse(edgeIndex, metaNodeMap, remainingEdges);
      size--;
    }
    return remainingEdges;
  };
  var elesfn$p = {
    // Computes the minimum cut of an undirected graph
    // Returns the correct answer with high probability
    kargerStein: function kargerStein() {
      var _this = this;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      edges.unmergeBy(function (edge) {
        return edge.isLoop();
      });
      var numNodes = nodes.length;
      var numEdges = edges.length;
      var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));
      var stopSize = Math.floor(numNodes / sqrt2);
      if (numNodes < 2) {
        error('At least 2 nodes are required for Karger-Stein algorithm');
        return undefined;
      }

      // Now store edge destination as indexes
      // Format for each edge (edge index, source node index, target node index)
      var edgeIndexes = [];
      for (var i = 0; i < numEdges; i++) {
        var e = edges[i];
        edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]);
      }

      // We will store the best cut found here
      var minCutSize = Infinity;
      var minCutEdgeIndexes = [];
      var minCutNodeMap = new Array(numNodes);

      // Initial meta node partition
      var metaNodeMap = new Array(numNodes);
      var metaNodeMap2 = new Array(numNodes);
      var copyNodesMap = function copyNodesMap(from, to) {
        for (var _i3 = 0; _i3 < numNodes; _i3++) {
          to[_i3] = from[_i3];
        }
      };

      // Main loop
      for (var iter = 0; iter <= numIter; iter++) {
        // Reset meta node partition
        for (var _i4 = 0; _i4 < numNodes; _i4++) {
          metaNodeMap[_i4] = _i4;
        }

        // Contract until stop point (stopSize nodes)
        var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize);
        var edgesState2 = edgesState.slice(); // copy

        // Create a copy of the colapsed nodes state
        copyNodesMap(metaNodeMap, metaNodeMap2);

        // Run 2 iterations starting in the stop state
        var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);
        var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2);

        // Is any of the 2 results the best cut so far?
        if (res1.length <= res2.length && res1.length < minCutSize) {
          minCutSize = res1.length;
          minCutEdgeIndexes = res1;
          copyNodesMap(metaNodeMap, minCutNodeMap);
        } else if (res2.length <= res1.length && res2.length < minCutSize) {
          minCutSize = res2.length;
          minCutEdgeIndexes = res2;
          copyNodesMap(metaNodeMap2, minCutNodeMap);
        }
      } // end of main loop

      // Construct result
      var cut = this.spawn(minCutEdgeIndexes.map(function (e) {
        return edges[e[0]];
      }));
      var partition1 = this.spawn();
      var partition2 = this.spawn();

      // traverse metaNodeMap for best cut
      var witnessNodePartition = minCutNodeMap[0];
      for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) {
        var partitionId = minCutNodeMap[_i5];
        var node = nodes[_i5];
        if (partitionId === witnessNodePartition) {
          partition1.merge(node);
        } else {
          partition2.merge(node);
        }
      }

      // construct components corresponding to each disjoint subset of nodes
      var constructComponent = function constructComponent(subset) {
        var component = _this.spawn();
        subset.forEach(function (node) {
          component.merge(node);
          node.connectedEdges().forEach(function (edge) {
            // ensure edge is within calling collection and edge is not in cut
            if (_this.contains(edge) && !cut.contains(edge)) {
              component.merge(edge);
            }
          });
        });
        return component;
      };
      var components = [constructComponent(partition1), constructComponent(partition2)];
      var ret = {
        cut: cut,
        components: components,
        // n.b. partitions are included to be compatible with the old api spec
        // (could be removed in a future major version)
        partition1: partition1,
        partition2: partition2
      };
      return ret;
    }
  }; // elesfn

  var copyPosition = function copyPosition(p) {
    return {
      x: p.x,
      y: p.y
    };
  };
  var modelToRenderedPosition = function modelToRenderedPosition(p, zoom, pan) {
    return {
      x: p.x * zoom + pan.x,
      y: p.y * zoom + pan.y
    };
  };
  var renderedToModelPosition = function renderedToModelPosition(p, zoom, pan) {
    return {
      x: (p.x - pan.x) / zoom,
      y: (p.y - pan.y) / zoom
    };
  };
  var array2point = function array2point(arr) {
    return {
      x: arr[0],
      y: arr[1]
    };
  };
  var min = function min(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var min = Infinity;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        min = Math.min(val, min);
      }
    }
    return min;
  };
  var max = function max(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var max = -Infinity;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        max = Math.max(val, max);
      }
    }
    return max;
  };
  var mean = function mean(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var total = 0;
    var n = 0;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        total += val;
        n++;
      }
    }
    return total / n;
  };
  var median = function median(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var copy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var sort = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var includeHoles = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    if (copy) {
      arr = arr.slice(begin, end);
    } else {
      if (end < arr.length) {
        arr.splice(end, arr.length - end);
      }
      if (begin > 0) {
        arr.splice(0, begin);
      }
    }

    // all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start
    var off = 0; // offset from non-finite values
    for (var i = arr.length - 1; i >= 0; i--) {
      var v = arr[i];
      if (includeHoles) {
        if (!isFinite(v)) {
          arr[i] = -Infinity;
          off++;
        }
      } else {
        // just remove it if we don't want to consider holes
        arr.splice(i, 1);
      }
    }
    if (sort) {
      arr.sort(function (a, b) {
        return a - b;
      }); // requires copy = true if you don't want to change the orig
    }

    var len = arr.length;
    var mid = Math.floor(len / 2);
    if (len % 2 !== 0) {
      return arr[mid + 1 + off];
    } else {
      return (arr[mid - 1 + off] + arr[mid + off]) / 2;
    }
  };
  var deg2rad = function deg2rad(deg) {
    return Math.PI * deg / 180;
  };
  var getAngleFromDisp = function getAngleFromDisp(dispX, dispY) {
    return Math.atan2(dispY, dispX) - Math.PI / 2;
  };
  var log2 = Math.log2 || function (n) {
    return Math.log(n) / Math.log(2);
  };
  var signum = function signum(x) {
    if (x > 0) {
      return 1;
    } else if (x < 0) {
      return -1;
    } else {
      return 0;
    }
  };
  var dist = function dist(p1, p2) {
    return Math.sqrt(sqdist(p1, p2));
  };
  var sqdist = function sqdist(p1, p2) {
    var dx = p2.x - p1.x;
    var dy = p2.y - p1.y;
    return dx * dx + dy * dy;
  };
  var inPlaceSumNormalize = function inPlaceSumNormalize(v) {
    var length = v.length;

    // First, get sum of all elements
    var total = 0;
    for (var i = 0; i < length; i++) {
      total += v[i];
    }

    // Now, divide each by the sum of all elements
    for (var _i = 0; _i < length; _i++) {
      v[_i] = v[_i] / total;
    }
    return v;
  };

  // from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves
  var qbezierAt = function qbezierAt(p0, p1, p2, t) {
    return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
  };
  var qbezierPtAt = function qbezierPtAt(p0, p1, p2, t) {
    return {
      x: qbezierAt(p0.x, p1.x, p2.x, t),
      y: qbezierAt(p0.y, p1.y, p2.y, t)
    };
  };
  var lineAt = function lineAt(p0, p1, t, d) {
    var vec = {
      x: p1.x - p0.x,
      y: p1.y - p0.y
    };
    var vecDist = dist(p0, p1);
    var normVec = {
      x: vec.x / vecDist,
      y: vec.y / vecDist
    };
    t = t == null ? 0 : t;
    d = d != null ? d : t * vecDist;
    return {
      x: p0.x + normVec.x * d,
      y: p0.y + normVec.y * d
    };
  };
  var bound = function bound(min, val, max) {
    return Math.max(min, Math.min(max, val));
  };

  // makes a full bb (x1, y1, x2, y2, w, h) from implicit params
  var makeBoundingBox = function makeBoundingBox(bb) {
    if (bb == null) {
      return {
        x1: Infinity,
        y1: Infinity,
        x2: -Infinity,
        y2: -Infinity,
        w: 0,
        h: 0
      };
    } else if (bb.x1 != null && bb.y1 != null) {
      if (bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1) {
        return {
          x1: bb.x1,
          y1: bb.y1,
          x2: bb.x2,
          y2: bb.y2,
          w: bb.x2 - bb.x1,
          h: bb.y2 - bb.y1
        };
      } else if (bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0) {
        return {
          x1: bb.x1,
          y1: bb.y1,
          x2: bb.x1 + bb.w,
          y2: bb.y1 + bb.h,
          w: bb.w,
          h: bb.h
        };
      }
    }
  };
  var copyBoundingBox = function copyBoundingBox(bb) {
    return {
      x1: bb.x1,
      x2: bb.x2,
      w: bb.w,
      y1: bb.y1,
      y2: bb.y2,
      h: bb.h
    };
  };
  var clearBoundingBox = function clearBoundingBox(bb) {
    bb.x1 = Infinity;
    bb.y1 = Infinity;
    bb.x2 = -Infinity;
    bb.y2 = -Infinity;
    bb.w = 0;
    bb.h = 0;
  };
  var shiftBoundingBox = function shiftBoundingBox(bb, dx, dy) {
    return {
      x1: bb.x1 + dx,
      x2: bb.x2 + dx,
      y1: bb.y1 + dy,
      y2: bb.y2 + dy,
      w: bb.w,
      h: bb.h
    };
  };
  var updateBoundingBox = function updateBoundingBox(bb1, bb2) {
    // update bb1 with bb2 bounds

    bb1.x1 = Math.min(bb1.x1, bb2.x1);
    bb1.x2 = Math.max(bb1.x2, bb2.x2);
    bb1.w = bb1.x2 - bb1.x1;
    bb1.y1 = Math.min(bb1.y1, bb2.y1);
    bb1.y2 = Math.max(bb1.y2, bb2.y2);
    bb1.h = bb1.y2 - bb1.y1;
  };
  var expandBoundingBoxByPoint = function expandBoundingBoxByPoint(bb, x, y) {
    bb.x1 = Math.min(bb.x1, x);
    bb.x2 = Math.max(bb.x2, x);
    bb.w = bb.x2 - bb.x1;
    bb.y1 = Math.min(bb.y1, y);
    bb.y2 = Math.max(bb.y2, y);
    bb.h = bb.y2 - bb.y1;
  };
  var expandBoundingBox = function expandBoundingBox(bb) {
    var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    bb.x1 -= padding;
    bb.x2 += padding;
    bb.y1 -= padding;
    bb.y2 += padding;
    bb.w = bb.x2 - bb.x1;
    bb.h = bb.y2 - bb.y1;
    return bb;
  };
  var expandBoundingBoxSides = function expandBoundingBoxSides(bb) {
    var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0];
    var top, right, bottom, left;
    if (padding.length === 1) {
      top = right = bottom = left = padding[0];
    } else if (padding.length === 2) {
      top = bottom = padding[0];
      left = right = padding[1];
    } else if (padding.length === 4) {
      var _padding = _slicedToArray(padding, 4);
      top = _padding[0];
      right = _padding[1];
      bottom = _padding[2];
      left = _padding[3];
    }
    bb.x1 -= left;
    bb.x2 += right;
    bb.y1 -= top;
    bb.y2 += bottom;
    bb.w = bb.x2 - bb.x1;
    bb.h = bb.y2 - bb.y1;
    return bb;
  };

  // assign the values of bb2 into bb1
  var assignBoundingBox = function assignBoundingBox(bb1, bb2) {
    bb1.x1 = bb2.x1;
    bb1.y1 = bb2.y1;
    bb1.x2 = bb2.x2;
    bb1.y2 = bb2.y2;
    bb1.w = bb1.x2 - bb1.x1;
    bb1.h = bb1.y2 - bb1.y1;
  };
  var boundingBoxesIntersect = function boundingBoxesIntersect(bb1, bb2) {
    // case: one bb to right of other
    if (bb1.x1 > bb2.x2) {
      return false;
    }
    if (bb2.x1 > bb1.x2) {
      return false;
    }

    // case: one bb to left of other
    if (bb1.x2 < bb2.x1) {
      return false;
    }
    if (bb2.x2 < bb1.x1) {
      return false;
    }

    // case: one bb above other
    if (bb1.y2 < bb2.y1) {
      return false;
    }
    if (bb2.y2 < bb1.y1) {
      return false;
    }

    // case: one bb below other
    if (bb1.y1 > bb2.y2) {
      return false;
    }
    if (bb2.y1 > bb1.y2) {
      return false;
    }

    // otherwise, must have some overlap
    return true;
  };
  var inBoundingBox = function inBoundingBox(bb, x, y) {
    return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;
  };
  var pointInBoundingBox = function pointInBoundingBox(bb, pt) {
    return inBoundingBox(bb, pt.x, pt.y);
  };
  var boundingBoxInBoundingBox = function boundingBoxInBoundingBox(bb1, bb2) {
    return inBoundingBox(bb1, bb2.x1, bb2.y1) && inBoundingBox(bb1, bb2.x2, bb2.y2);
  };
  var roundRectangleIntersectLine = function roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding) {
    var cornerRadius = getRoundRectangleRadius(width, height);
    var halfWidth = width / 2;
    var halfHeight = height / 2;

    // Check intersections with straight line segments
    var straightLineIntersections;

    // Top segment, left to right
    {
      var topStartX = nodeX - halfWidth + cornerRadius - padding;
      var topStartY = nodeY - halfHeight - padding;
      var topEndX = nodeX + halfWidth - cornerRadius + padding;
      var topEndY = topStartY;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Right segment, top to bottom
    {
      var rightStartX = nodeX + halfWidth + padding;
      var rightStartY = nodeY - halfHeight + cornerRadius - padding;
      var rightEndX = rightStartX;
      var rightEndY = nodeY + halfHeight - cornerRadius + padding;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Bottom segment, left to right
    {
      var bottomStartX = nodeX - halfWidth + cornerRadius - padding;
      var bottomStartY = nodeY + halfHeight + padding;
      var bottomEndX = nodeX + halfWidth - cornerRadius + padding;
      var bottomEndY = bottomStartY;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Left segment, top to bottom
    {
      var leftStartX = nodeX - halfWidth - padding;
      var leftStartY = nodeY - halfHeight + cornerRadius - padding;
      var leftEndX = leftStartX;
      var leftEndY = nodeY + halfHeight - cornerRadius + padding;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Check intersections with arc segments
    var arcIntersections;

    // Top Left
    {
      var topLeftCenterX = nodeX - halfWidth + cornerRadius;
      var topLeftCenterY = nodeY - halfHeight + cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topLeftCenterX, topLeftCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] <= topLeftCenterX && arcIntersections[1] <= topLeftCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Top Right
    {
      var topRightCenterX = nodeX + halfWidth - cornerRadius;
      var topRightCenterY = nodeY - halfHeight + cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topRightCenterX, topRightCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] >= topRightCenterX && arcIntersections[1] <= topRightCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Bottom Right
    {
      var bottomRightCenterX = nodeX + halfWidth - cornerRadius;
      var bottomRightCenterY = nodeY + halfHeight - cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomRightCenterX, bottomRightCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] >= bottomRightCenterX && arcIntersections[1] >= bottomRightCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Bottom Left
    {
      var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;
      var bottomLeftCenterY = nodeY + halfHeight - cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] <= bottomLeftCenterX && arcIntersections[1] >= bottomLeftCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }
    return []; // if nothing
  };

  var inLineVicinity = function inLineVicinity(x, y, lx1, ly1, lx2, ly2, tolerance) {
    var t = tolerance;
    var x1 = Math.min(lx1, lx2);
    var x2 = Math.max(lx1, lx2);
    var y1 = Math.min(ly1, ly2);
    var y2 = Math.max(ly1, ly2);
    return x1 - t <= x && x <= x2 + t && y1 - t <= y && y <= y2 + t;
  };
  var inBezierVicinity = function inBezierVicinity(x, y, x1, y1, x2, y2, x3, y3, tolerance) {
    var bb = {
      x1: Math.min(x1, x3, x2) - tolerance,
      x2: Math.max(x1, x3, x2) + tolerance,
      y1: Math.min(y1, y3, y2) - tolerance,
      y2: Math.max(y1, y3, y2) + tolerance
    };

    // if outside the rough bounding box for the bezier, then it can't be a hit
    if (x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2) {
      // console.log('bezier out of rough bb')
      return false;
    } else {
      // console.log('do more expensive check');
      return true;
    }
  };
  var solveQuadratic = function solveQuadratic(a, b, c, val) {
    c -= val;
    var r = b * b - 4 * a * c;
    if (r < 0) {
      return [];
    }
    var sqrtR = Math.sqrt(r);
    var denom = 2 * a;
    var root1 = (-b + sqrtR) / denom;
    var root2 = (-b - sqrtR) / denom;
    return [root1, root2];
  };
  var solveCubic = function solveCubic(a, b, c, d, result) {
    // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where
    // r is the real component, i is the imaginary component

    // An implementation of the Cardano method from the year 1545
    // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots

    var epsilon = 0.00001;

    // avoid division by zero while keeping the overall expression close in value
    if (a === 0) {
      a = epsilon;
    }
    b /= a;
    c /= a;
    d /= a;
    var discriminant, q, r, dum1, s, t, term1, r13;
    q = (3.0 * c - b * b) / 9.0;
    r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));
    r /= 54.0;
    discriminant = q * q * q + r * r;
    result[1] = 0;
    term1 = b / 3.0;
    if (discriminant > 0) {
      s = r + Math.sqrt(discriminant);
      s = s < 0 ? -Math.pow(-s, 1.0 / 3.0) : Math.pow(s, 1.0 / 3.0);
      t = r - Math.sqrt(discriminant);
      t = t < 0 ? -Math.pow(-t, 1.0 / 3.0) : Math.pow(t, 1.0 / 3.0);
      result[0] = -term1 + s + t;
      term1 += (s + t) / 2.0;
      result[4] = result[2] = -term1;
      term1 = Math.sqrt(3.0) * (-t + s) / 2;
      result[3] = term1;
      result[5] = -term1;
      return;
    }
    result[5] = result[3] = 0;
    if (discriminant === 0) {
      r13 = r < 0 ? -Math.pow(-r, 1.0 / 3.0) : Math.pow(r, 1.0 / 3.0);
      result[0] = -term1 + 2.0 * r13;
      result[4] = result[2] = -(r13 + term1);
      return;
    }
    q = -q;
    dum1 = q * q * q;
    dum1 = Math.acos(r / Math.sqrt(dum1));
    r13 = 2.0 * Math.sqrt(q);
    result[0] = -term1 + r13 * Math.cos(dum1 / 3.0);
    result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);
    result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);
    return;
  };
  var sqdistToQuadraticBezier = function sqdistToQuadraticBezier(x, y, x1, y1, x2, y2, x3, y3) {
    // Find minimum distance by using the minimum of the distance
    // function between the given point and the curve

    // This gives the coefficients of the resulting cubic equation
    // whose roots tell us where a possible minimum is
    // (Coefficients are divided by 4)

    var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3 + y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3;
    var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3 + 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3;
    var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x + 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y;
    var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x + y1 * y2 - y1 * y1 + y1 * y - y2 * y;

    // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a);

    var roots = [];

    // Use the cubic solving algorithm
    solveCubic(a, b, c, d, roots);
    var zeroThreshold = 0.0000001;
    var params = [];
    for (var index = 0; index < 6; index += 2) {
      if (Math.abs(roots[index + 1]) < zeroThreshold && roots[index] >= 0 && roots[index] <= 1.0) {
        params.push(roots[index]);
      }
    }
    params.push(1.0);
    params.push(0.0);
    var minDistanceSquared = -1;
    var curX, curY, distSquared;
    for (var i = 0; i < params.length; i++) {
      curX = Math.pow(1.0 - params[i], 2.0) * x1 + 2.0 * (1 - params[i]) * params[i] * x2 + params[i] * params[i] * x3;
      curY = Math.pow(1 - params[i], 2.0) * y1 + 2 * (1.0 - params[i]) * params[i] * y2 + params[i] * params[i] * y3;
      distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2);
      // debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared));
      if (minDistanceSquared >= 0) {
        if (distSquared < minDistanceSquared) {
          minDistanceSquared = distSquared;
        }
      } else {
        minDistanceSquared = distSquared;
      }
    }
    return minDistanceSquared;
  };
  var sqdistToFiniteLine = function sqdistToFiniteLine(x, y, x1, y1, x2, y2) {
    var offset = [x - x1, y - y1];
    var line = [x2 - x1, y2 - y1];
    var lineSq = line[0] * line[0] + line[1] * line[1];
    var hypSq = offset[0] * offset[0] + offset[1] * offset[1];
    var dotProduct = offset[0] * line[0] + offset[1] * line[1];
    var adjSq = dotProduct * dotProduct / lineSq;
    if (dotProduct < 0) {
      return hypSq;
    }
    if (adjSq > lineSq) {
      return (x - x2) * (x - x2) + (y - y2) * (y - y2);
    }
    return hypSq - adjSq;
  };
  var pointInsidePolygonPoints = function pointInsidePolygonPoints(x, y, points) {
    var x1, y1, x2, y2;
    var y3;

    // Intersect with vertical line through (x, y)
    var up = 0;
    // let down = 0;
    for (var i = 0; i < points.length / 2; i++) {
      x1 = points[i * 2];
      y1 = points[i * 2 + 1];
      if (i + 1 < points.length / 2) {
        x2 = points[(i + 1) * 2];
        y2 = points[(i + 1) * 2 + 1];
      } else {
        x2 = points[(i + 1 - points.length / 2) * 2];
        y2 = points[(i + 1 - points.length / 2) * 2 + 1];
      }
      if (x1 == x && x2 == x) ; else if (x1 >= x && x >= x2 || x1 <= x && x <= x2) {
        y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;
        if (y3 > y) {
          up++;
        }

        // if( y3 < y ){
        // down++;
        // }
      } else {
        continue;
      }
    }
    if (up % 2 === 0) {
      return false;
    } else {
      return true;
    }
  };
  var pointInsidePolygon = function pointInsidePolygon(x, y, basePoints, centerX, centerY, width, height, direction, padding) {
    var transformedPoints = new Array(basePoints.length);

    // Gives negative angle
    var angle;
    if (direction[0] != null) {
      angle = Math.atan(direction[1] / direction[0]);
      if (direction[0] < 0) {
        angle = angle + Math.PI / 2;
      } else {
        angle = -angle - Math.PI / 2;
      }
    } else {
      angle = direction;
    }
    var cos = Math.cos(-angle);
    var sin = Math.sin(-angle);

    //    console.log("base: " + basePoints);
    for (var i = 0; i < transformedPoints.length / 2; i++) {
      transformedPoints[i * 2] = width / 2 * (basePoints[i * 2] * cos - basePoints[i * 2 + 1] * sin);
      transformedPoints[i * 2 + 1] = height / 2 * (basePoints[i * 2 + 1] * cos + basePoints[i * 2] * sin);
      transformedPoints[i * 2] += centerX;
      transformedPoints[i * 2 + 1] += centerY;
    }
    var points;
    if (padding > 0) {
      var expandedLineSet = expandPolygon(transformedPoints, -padding);
      points = joinLines(expandedLineSet);
    } else {
      points = transformedPoints;
    }
    return pointInsidePolygonPoints(x, y, points);
  };
  var pointInsideRoundPolygon = function pointInsideRoundPolygon(x, y, basePoints, centerX, centerY, width, height) {
    var cutPolygonPoints = new Array(basePoints.length);
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    var squaredCornerRadius = cornerRadius * cornerRadius;
    for (var i = 0; i < basePoints.length / 4; i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (i === 0) {
        sourceUv = basePoints.length - 2;
      } else {
        sourceUv = i * 4 - 2;
      }
      destUv = i * 4 + 2;
      var px = centerX + halfW * basePoints[i * 4];
      var py = centerY + halfH * basePoints[i * 4 + 1];
      var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * basePoints[sourceUv];
      var cp0y = py - offset * basePoints[sourceUv + 1];
      var cp1x = px + offset * basePoints[destUv];
      var cp1y = py + offset * basePoints[destUv + 1];
      cutPolygonPoints[i * 4] = cp0x;
      cutPolygonPoints[i * 4 + 1] = cp0y;
      cutPolygonPoints[i * 4 + 2] = cp1x;
      cutPolygonPoints[i * 4 + 3] = cp1y;
      var orthx = basePoints[sourceUv + 1];
      var orthy = -basePoints[sourceUv];
      var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1];
      if (cosAlpha < 0) {
        orthx *= -1;
        orthy *= -1;
      }
      var cx = cp0x + orthx * cornerRadius;
      var cy = cp0y + orthy * cornerRadius;
      var squaredDistance = Math.pow(cx - x, 2) + Math.pow(cy - y, 2);
      if (squaredDistance <= squaredCornerRadius) {
        return true;
      }
    }
    return pointInsidePolygonPoints(x, y, cutPolygonPoints);
  };
  var joinLines = function joinLines(lineSet) {
    var vertices = new Array(lineSet.length / 2);
    var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;
    var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;
    for (var i = 0; i < lineSet.length / 4; i++) {
      currentLineStartX = lineSet[i * 4];
      currentLineStartY = lineSet[i * 4 + 1];
      currentLineEndX = lineSet[i * 4 + 2];
      currentLineEndY = lineSet[i * 4 + 3];
      if (i < lineSet.length / 4 - 1) {
        nextLineStartX = lineSet[(i + 1) * 4];
        nextLineStartY = lineSet[(i + 1) * 4 + 1];
        nextLineEndX = lineSet[(i + 1) * 4 + 2];
        nextLineEndY = lineSet[(i + 1) * 4 + 3];
      } else {
        nextLineStartX = lineSet[0];
        nextLineStartY = lineSet[1];
        nextLineEndX = lineSet[2];
        nextLineEndY = lineSet[3];
      }
      var intersection = finiteLinesIntersect(currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY, nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY, true);
      vertices[i * 2] = intersection[0];
      vertices[i * 2 + 1] = intersection[1];
    }
    return vertices;
  };
  var expandPolygon = function expandPolygon(points, pad) {
    var expandedLineSet = new Array(points.length * 2);
    var currentPointX, currentPointY, nextPointX, nextPointY;
    for (var i = 0; i < points.length / 2; i++) {
      currentPointX = points[i * 2];
      currentPointY = points[i * 2 + 1];
      if (i < points.length / 2 - 1) {
        nextPointX = points[(i + 1) * 2];
        nextPointY = points[(i + 1) * 2 + 1];
      } else {
        nextPointX = points[0];
        nextPointY = points[1];
      }

      // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]

      // Assume CCW polygon winding

      var offsetX = nextPointY - currentPointY;
      var offsetY = -(nextPointX - currentPointX);

      // Normalize
      var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
      var normalizedOffsetX = offsetX / offsetLength;
      var normalizedOffsetY = offsetY / offsetLength;
      expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad;
      expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad;
      expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad;
      expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad;
    }
    return expandedLineSet;
  };
  var intersectLineEllipse = function intersectLineEllipse(x, y, centerX, centerY, ellipseWradius, ellipseHradius) {
    var dispX = centerX - x;
    var dispY = centerY - y;
    dispX /= ellipseWradius;
    dispY /= ellipseHradius;
    var len = Math.sqrt(dispX * dispX + dispY * dispY);
    var newLength = len - 1;
    if (newLength < 0) {
      return [];
    }
    var lenProportion = newLength / len;
    return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y];
  };
  var checkInEllipse = function checkInEllipse(x, y, width, height, centerX, centerY, padding) {
    x -= centerX;
    y -= centerY;
    x /= width / 2 + padding;
    y /= height / 2 + padding;
    return x * x + y * y <= 1;
  };

  // Returns intersections of increasing distance from line's start point
  var intersectLineCircle = function intersectLineCircle(x1, y1, x2, y2, centerX, centerY, radius) {
    // Calculate d, direction vector of line
    var d = [x2 - x1, y2 - y1]; // Direction vector of line
    var f = [x1 - centerX, y1 - centerY];
    var a = d[0] * d[0] + d[1] * d[1];
    var b = 2 * (f[0] * d[0] + f[1] * d[1]);
    var c = f[0] * f[0] + f[1] * f[1] - radius * radius;
    var discriminant = b * b - 4 * a * c;
    if (discriminant < 0) {
      return [];
    }
    var t1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    var t2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    var tMin = Math.min(t1, t2);
    var tMax = Math.max(t1, t2);
    var inRangeParams = [];
    if (tMin >= 0 && tMin <= 1) {
      inRangeParams.push(tMin);
    }
    if (tMax >= 0 && tMax <= 1) {
      inRangeParams.push(tMax);
    }
    if (inRangeParams.length === 0) {
      return [];
    }
    var nearIntersectionX = inRangeParams[0] * d[0] + x1;
    var nearIntersectionY = inRangeParams[0] * d[1] + y1;
    if (inRangeParams.length > 1) {
      if (inRangeParams[0] == inRangeParams[1]) {
        return [nearIntersectionX, nearIntersectionY];
      } else {
        var farIntersectionX = inRangeParams[1] * d[0] + x1;
        var farIntersectionY = inRangeParams[1] * d[1] + y1;
        return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY];
      }
    } else {
      return [nearIntersectionX, nearIntersectionY];
    }
  };
  var midOfThree = function midOfThree(a, b, c) {
    if (b <= a && a <= c || c <= a && a <= b) {
      return a;
    } else if (a <= b && b <= c || c <= b && b <= a) {
      return b;
    } else {
      return c;
    }
  };

  // (x1,y1)=>(x2,y2) intersect with (x3,y3)=>(x4,y4)
  var finiteLinesIntersect = function finiteLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) {
    var dx13 = x1 - x3;
    var dx21 = x2 - x1;
    var dx43 = x4 - x3;
    var dy13 = y1 - y3;
    var dy21 = y2 - y1;
    var dy43 = y4 - y3;
    var ua_t = dx43 * dy13 - dy43 * dx13;
    var ub_t = dx21 * dy13 - dy21 * dx13;
    var u_b = dy43 * dx21 - dx43 * dy21;
    if (u_b !== 0) {
      var ua = ua_t / u_b;
      var ub = ub_t / u_b;
      var flptThreshold = 0.001;
      var _min = 0 - flptThreshold;
      var _max = 1 + flptThreshold;
      if (_min <= ua && ua <= _max && _min <= ub && ub <= _max) {
        return [x1 + ua * dx21, y1 + ua * dy21];
      } else {
        if (!infiniteLines) {
          return [];
        } else {
          return [x1 + ua * dx21, y1 + ua * dy21];
        }
      }
    } else {
      if (ua_t === 0 || ub_t === 0) {
        // Parallel, coincident lines. Check if overlap

        // Check endpoint of second line
        if (midOfThree(x1, x2, x4) === x4) {
          return [x4, y4];
        }

        // Check start point of second line
        if (midOfThree(x1, x2, x3) === x3) {
          return [x3, y3];
        }

        // Endpoint of first line
        if (midOfThree(x3, x4, x2) === x2) {
          return [x2, y2];
        }
        return [];
      } else {
        // Parallel, non-coincident
        return [];
      }
    }
  };

  // math.polygonIntersectLine( x, y, basePoints, centerX, centerY, width, height, padding )
  // intersect a node polygon (pts transformed)
  //
  // math.polygonIntersectLine( x, y, basePoints, centerX, centerY )
  // intersect the points (no transform)
  var polygonIntersectLine = function polygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) {
    var intersections = [];
    var intersection;
    var transformedPoints = new Array(basePoints.length);
    var doTransform = true;
    if (width == null) {
      doTransform = false;
    }
    var points;
    if (doTransform) {
      for (var i = 0; i < transformedPoints.length / 2; i++) {
        transformedPoints[i * 2] = basePoints[i * 2] * width + centerX;
        transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY;
      }
      if (padding > 0) {
        var expandedLineSet = expandPolygon(transformedPoints, -padding);
        points = joinLines(expandedLineSet);
      } else {
        points = transformedPoints;
      }
    } else {
      points = basePoints;
    }
    var currentX, currentY, nextX, nextY;
    for (var _i2 = 0; _i2 < points.length / 2; _i2++) {
      currentX = points[_i2 * 2];
      currentY = points[_i2 * 2 + 1];
      if (_i2 < points.length / 2 - 1) {
        nextX = points[(_i2 + 1) * 2];
        nextY = points[(_i2 + 1) * 2 + 1];
      } else {
        nextX = points[0];
        nextY = points[1];
      }
      intersection = finiteLinesIntersect(x, y, centerX, centerY, currentX, currentY, nextX, nextY);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    return intersections;
  };
  var roundPolygonIntersectLine = function roundPolygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) {
    var intersections = [];
    var intersection;
    var lines = new Array(basePoints.length);
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    for (var i = 0; i < basePoints.length / 4; i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (i === 0) {
        sourceUv = basePoints.length - 2;
      } else {
        sourceUv = i * 4 - 2;
      }
      destUv = i * 4 + 2;
      var px = centerX + halfW * basePoints[i * 4];
      var py = centerY + halfH * basePoints[i * 4 + 1];
      var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * basePoints[sourceUv];
      var cp0y = py - offset * basePoints[sourceUv + 1];
      var cp1x = px + offset * basePoints[destUv];
      var cp1y = py + offset * basePoints[destUv + 1];
      if (i === 0) {
        lines[basePoints.length - 2] = cp0x;
        lines[basePoints.length - 1] = cp0y;
      } else {
        lines[i * 4 - 2] = cp0x;
        lines[i * 4 - 1] = cp0y;
      }
      lines[i * 4] = cp1x;
      lines[i * 4 + 1] = cp1y;
      var orthx = basePoints[sourceUv + 1];
      var orthy = -basePoints[sourceUv];
      var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1];
      if (cosAlpha < 0) {
        orthx *= -1;
        orthy *= -1;
      }
      var cx = cp0x + orthx * cornerRadius;
      var cy = cp0y + orthy * cornerRadius;
      intersection = intersectLineCircle(x, y, centerX, centerY, cx, cy, cornerRadius);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    for (var _i3 = 0; _i3 < lines.length / 4; _i3++) {
      intersection = finiteLinesIntersect(x, y, centerX, centerY, lines[_i3 * 4], lines[_i3 * 4 + 1], lines[_i3 * 4 + 2], lines[_i3 * 4 + 3], false);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    if (intersections.length > 2) {
      var lowestIntersection = [intersections[0], intersections[1]];
      var lowestSquaredDistance = Math.pow(lowestIntersection[0] - x, 2) + Math.pow(lowestIntersection[1] - y, 2);
      for (var _i4 = 1; _i4 < intersections.length / 2; _i4++) {
        var squaredDistance = Math.pow(intersections[_i4 * 2] - x, 2) + Math.pow(intersections[_i4 * 2 + 1] - y, 2);
        if (squaredDistance <= lowestSquaredDistance) {
          lowestIntersection[0] = intersections[_i4 * 2];
          lowestIntersection[1] = intersections[_i4 * 2 + 1];
          lowestSquaredDistance = squaredDistance;
        }
      }
      return lowestIntersection;
    }
    return intersections;
  };
  var shortenIntersection = function shortenIntersection(intersection, offset, amount) {
    var disp = [intersection[0] - offset[0], intersection[1] - offset[1]];
    var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]);
    var lenRatio = (length - amount) / length;
    if (lenRatio < 0) {
      lenRatio = 0.00001;
    }
    return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]];
  };
  var generateUnitNgonPointsFitToSquare = function generateUnitNgonPointsFitToSquare(sides, rotationRadians) {
    var points = generateUnitNgonPoints(sides, rotationRadians);
    points = fitPolygonToSquare(points);
    return points;
  };
  var fitPolygonToSquare = function fitPolygonToSquare(points) {
    var x, y;
    var sides = points.length / 2;
    var minX = Infinity,
      minY = Infinity,
      maxX = -Infinity,
      maxY = -Infinity;
    for (var i = 0; i < sides; i++) {
      x = points[2 * i];
      y = points[2 * i + 1];
      minX = Math.min(minX, x);
      maxX = Math.max(maxX, x);
      minY = Math.min(minY, y);
      maxY = Math.max(maxY, y);
    }

    // stretch factors
    var sx = 2 / (maxX - minX);
    var sy = 2 / (maxY - minY);
    for (var _i5 = 0; _i5 < sides; _i5++) {
      x = points[2 * _i5] = points[2 * _i5] * sx;
      y = points[2 * _i5 + 1] = points[2 * _i5 + 1] * sy;
      minX = Math.min(minX, x);
      maxX = Math.max(maxX, x);
      minY = Math.min(minY, y);
      maxY = Math.max(maxY, y);
    }
    if (minY < -1) {
      for (var _i6 = 0; _i6 < sides; _i6++) {
        y = points[2 * _i6 + 1] = points[2 * _i6 + 1] + (-1 - minY);
      }
    }
    return points;
  };
  var generateUnitNgonPoints = function generateUnitNgonPoints(sides, rotationRadians) {
    var increment = 1.0 / sides * 2 * Math.PI;
    var startAngle = sides % 2 === 0 ? Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;
    startAngle += rotationRadians;
    var points = new Array(sides * 2);
    var currentAngle;
    for (var i = 0; i < sides; i++) {
      currentAngle = i * increment + startAngle;
      points[2 * i] = Math.cos(currentAngle); // x
      points[2 * i + 1] = Math.sin(-currentAngle); // y
    }

    return points;
  };

  // Set the default radius, unless half of width or height is smaller than default
  var getRoundRectangleRadius = function getRoundRectangleRadius(width, height) {
    return Math.min(width / 4, height / 4, 8);
  };

  // Set the default radius
  var getRoundPolygonRadius = function getRoundPolygonRadius(width, height) {
    return Math.min(width / 10, height / 10, 8);
  };
  var getCutRectangleCornerLength = function getCutRectangleCornerLength() {
    return 8;
  };
  var bezierPtsToQuadCoeff = function bezierPtsToQuadCoeff(p0, p1, p2) {
    return [p0 - 2 * p1 + p2, 2 * (p1 - p0), p0];
  };

  // get curve width, height, and control point position offsets as a percentage of node height / width
  var getBarrelCurveConstants = function getBarrelCurveConstants(width, height) {
    return {
      heightOffset: Math.min(15, 0.05 * height),
      widthOffset: Math.min(100, 0.25 * width),
      ctrlPtOffsetPct: 0.05
    };
  };

  var pageRankDefaults = defaults$g({
    dampingFactor: 0.8,
    precision: 0.000001,
    iterations: 200,
    weight: function weight(edge) {
      return 1;
    }
  });
  var elesfn$o = {
    pageRank: function pageRank(options) {
      var _pageRankDefaults = pageRankDefaults(options),
        dampingFactor = _pageRankDefaults.dampingFactor,
        precision = _pageRankDefaults.precision,
        iterations = _pageRankDefaults.iterations,
        weight = _pageRankDefaults.weight;
      var cy = this._private.cy;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var numNodes = nodes.length;
      var numNodesSqd = numNodes * numNodes;
      var numEdges = edges.length;

      // Construct transposed adjacency matrix
      // First lets have a zeroed matrix of the right size
      // We'll also keep track of the sum of each column
      var matrix = new Array(numNodesSqd);
      var columnSum = new Array(numNodes);
      var additionalProb = (1 - dampingFactor) / numNodes;

      // Create null matrix
      for (var i = 0; i < numNodes; i++) {
        for (var j = 0; j < numNodes; j++) {
          var n = i * numNodes + j;
          matrix[n] = 0;
        }
        columnSum[i] = 0;
      }

      // Now, process edges
      for (var _i = 0; _i < numEdges; _i++) {
        var edge = edges[_i];
        var srcId = edge.data('source');
        var tgtId = edge.data('target');

        // Don't include loops in the matrix
        if (srcId === tgtId) {
          continue;
        }
        var s = nodes.indexOfId(srcId);
        var t = nodes.indexOfId(tgtId);
        var w = weight(edge);
        var _n = t * numNodes + s;

        // Update matrix
        matrix[_n] += w;

        // Update column sum
        columnSum[s] += w;
      }

      // Add additional probability based on damping factor
      // Also, take into account columns that have sum = 0
      var p = 1.0 / numNodes + additionalProb; // Shorthand

      // Traverse matrix, column by column
      for (var _j = 0; _j < numNodes; _j++) {
        if (columnSum[_j] === 0) {
          // No 'links' out from node jth, assume equal probability for each possible node
          for (var _i2 = 0; _i2 < numNodes; _i2++) {
            var _n2 = _i2 * numNodes + _j;
            matrix[_n2] = p;
          }
        } else {
          // Node jth has outgoing link, compute normalized probabilities
          for (var _i3 = 0; _i3 < numNodes; _i3++) {
            var _n3 = _i3 * numNodes + _j;
            matrix[_n3] = matrix[_n3] / columnSum[_j] + additionalProb;
          }
        }
      }

      // Compute dominant eigenvector using power method
      var eigenvector = new Array(numNodes);
      var temp = new Array(numNodes);
      var previous;

      // Start with a vector of all 1's
      // Also, initialize a null vector which will be used as shorthand
      for (var _i4 = 0; _i4 < numNodes; _i4++) {
        eigenvector[_i4] = 1;
      }
      for (var iter = 0; iter < iterations; iter++) {
        // Temp array with all 0's
        for (var _i5 = 0; _i5 < numNodes; _i5++) {
          temp[_i5] = 0;
        }

        // Multiply matrix with previous result
        for (var _i6 = 0; _i6 < numNodes; _i6++) {
          for (var _j2 = 0; _j2 < numNodes; _j2++) {
            var _n4 = _i6 * numNodes + _j2;
            temp[_i6] += matrix[_n4] * eigenvector[_j2];
          }
        }
        inPlaceSumNormalize(temp);
        previous = eigenvector;
        eigenvector = temp;
        temp = previous;
        var diff = 0;
        // Compute difference (squared module) of both vectors
        for (var _i7 = 0; _i7 < numNodes; _i7++) {
          var delta = previous[_i7] - eigenvector[_i7];
          diff += delta * delta;
        }

        // If difference is less than the desired threshold, stop iterating
        if (diff < precision) {
          break;
        }
      }

      // Construct result
      var res = {
        rank: function rank(node) {
          node = cy.collection(node)[0];
          return eigenvector[nodes.indexOf(node)];
        }
      };
      return res;
    } // pageRank
  }; // elesfn

  var defaults$f = defaults$g({
    root: null,
    weight: function weight(edge) {
      return 1;
    },
    directed: false,
    alpha: 0
  });
  var elesfn$n = {
    degreeCentralityNormalized: function degreeCentralityNormalized(options) {
      options = defaults$f(options);
      var cy = this.cy();
      var nodes = this.nodes();
      var numNodes = nodes.length;
      if (!options.directed) {
        var degrees = {};
        var maxDegree = 0;
        for (var i = 0; i < numNodes; i++) {
          var node = nodes[i];

          // add current node to the current options object and call degreeCentrality
          options.root = node;
          var currDegree = this.degreeCentrality(options);
          if (maxDegree < currDegree.degree) {
            maxDegree = currDegree.degree;
          }
          degrees[node.id()] = currDegree.degree;
        }
        return {
          degree: function degree(node) {
            if (maxDegree === 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return degrees[node.id()] / maxDegree;
          }
        };
      } else {
        var indegrees = {};
        var outdegrees = {};
        var maxIndegree = 0;
        var maxOutdegree = 0;
        for (var _i = 0; _i < numNodes; _i++) {
          var _node = nodes[_i];
          var id = _node.id();

          // add current node to the current options object and call degreeCentrality
          options.root = _node;
          var _currDegree = this.degreeCentrality(options);
          if (maxIndegree < _currDegree.indegree) maxIndegree = _currDegree.indegree;
          if (maxOutdegree < _currDegree.outdegree) maxOutdegree = _currDegree.outdegree;
          indegrees[id] = _currDegree.indegree;
          outdegrees[id] = _currDegree.outdegree;
        }
        return {
          indegree: function indegree(node) {
            if (maxIndegree == 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return indegrees[node.id()] / maxIndegree;
          },
          outdegree: function outdegree(node) {
            if (maxOutdegree === 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return outdegrees[node.id()] / maxOutdegree;
          }
        };
      }
    },
    // degreeCentralityNormalized

    // Implemented from the algorithm in Opsahl's paper
    // "Node centrality in weighted networks: Generalizing degree and shortest paths"
    // check the heading 2 "Degree"
    degreeCentrality: function degreeCentrality(options) {
      options = defaults$f(options);
      var cy = this.cy();
      var callingEles = this;
      var _options = options,
        root = _options.root,
        weight = _options.weight,
        directed = _options.directed,
        alpha = _options.alpha;
      root = cy.collection(root)[0];
      if (!directed) {
        var connEdges = root.connectedEdges().intersection(callingEles);
        var k = connEdges.length;
        var s = 0;

        // Now, sum edge weights
        for (var i = 0; i < connEdges.length; i++) {
          s += weight(connEdges[i]);
        }
        return {
          degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha)
        };
      } else {
        var edges = root.connectedEdges();
        var incoming = edges.filter(function (edge) {
          return edge.target().same(root) && callingEles.has(edge);
        });
        var outgoing = edges.filter(function (edge) {
          return edge.source().same(root) && callingEles.has(edge);
        });
        var k_in = incoming.length;
        var k_out = outgoing.length;
        var s_in = 0;
        var s_out = 0;

        // Now, sum incoming edge weights
        for (var _i2 = 0; _i2 < incoming.length; _i2++) {
          s_in += weight(incoming[_i2]);
        }

        // Now, sum outgoing edge weights
        for (var _i3 = 0; _i3 < outgoing.length; _i3++) {
          s_out += weight(outgoing[_i3]);
        }
        return {
          indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha),
          outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha)
        };
      }
    } // degreeCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$n.dc = elesfn$n.degreeCentrality;
  elesfn$n.dcn = elesfn$n.degreeCentralityNormalised = elesfn$n.degreeCentralityNormalized;

  var defaults$e = defaults$g({
    harmonic: true,
    weight: function weight() {
      return 1;
    },
    directed: false,
    root: null
  });
  var elesfn$m = {
    closenessCentralityNormalized: function closenessCentralityNormalized(options) {
      var _defaults = defaults$e(options),
        harmonic = _defaults.harmonic,
        weight = _defaults.weight,
        directed = _defaults.directed;
      var cy = this.cy();
      var closenesses = {};
      var maxCloseness = 0;
      var nodes = this.nodes();
      var fw = this.floydWarshall({
        weight: weight,
        directed: directed
      });

      // Compute closeness for every node and find the maximum closeness
      for (var i = 0; i < nodes.length; i++) {
        var currCloseness = 0;
        var node_i = nodes[i];
        for (var j = 0; j < nodes.length; j++) {
          if (i !== j) {
            var d = fw.distance(node_i, nodes[j]);
            if (harmonic) {
              currCloseness += 1 / d;
            } else {
              currCloseness += d;
            }
          }
        }
        if (!harmonic) {
          currCloseness = 1 / currCloseness;
        }
        if (maxCloseness < currCloseness) {
          maxCloseness = currCloseness;
        }
        closenesses[node_i.id()] = currCloseness;
      }
      return {
        closeness: function closeness(node) {
          if (maxCloseness == 0) {
            return 0;
          }
          if (string(node)) {
            // from is a selector string
            node = cy.filter(node)[0].id();
          } else {
            // from is a node
            node = node.id();
          }
          return closenesses[node] / maxCloseness;
        }
      };
    },
    // Implemented from pseudocode from wikipedia
    closenessCentrality: function closenessCentrality(options) {
      var _defaults2 = defaults$e(options),
        root = _defaults2.root,
        weight = _defaults2.weight,
        directed = _defaults2.directed,
        harmonic = _defaults2.harmonic;
      root = this.filter(root)[0];

      // we need distance from this node to every other node
      var dijkstra = this.dijkstra({
        root: root,
        weight: weight,
        directed: directed
      });
      var totalDistance = 0;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        var n = nodes[i];
        if (!n.same(root)) {
          var d = dijkstra.distanceTo(n);
          if (harmonic) {
            totalDistance += 1 / d;
          } else {
            totalDistance += d;
          }
        }
      }
      return harmonic ? totalDistance : 1 / totalDistance;
    } // closenessCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$m.cc = elesfn$m.closenessCentrality;
  elesfn$m.ccn = elesfn$m.closenessCentralityNormalised = elesfn$m.closenessCentralityNormalized;

  var defaults$d = defaults$g({
    weight: null,
    directed: false
  });
  var elesfn$l = {
    // Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes
    betweennessCentrality: function betweennessCentrality(options) {
      var _defaults = defaults$d(options),
        directed = _defaults.directed,
        weight = _defaults.weight;
      var weighted = weight != null;
      var cy = this.cy();

      // starting
      var V = this.nodes();
      var A = {};
      var _C = {};
      var max = 0;
      var C = {
        set: function set(key, val) {
          _C[key] = val;
          if (val > max) {
            max = val;
          }
        },
        get: function get(key) {
          return _C[key];
        }
      };

      // A contains the neighborhoods of every node
      for (var i = 0; i < V.length; i++) {
        var v = V[i];
        var vid = v.id();
        if (directed) {
          A[vid] = v.outgoers().nodes(); // get outgoers of every node
        } else {
          A[vid] = v.openNeighborhood().nodes(); // get neighbors of every node
        }

        C.set(vid, 0);
      }
      var _loop = function _loop(s) {
        var sid = V[s].id();
        var S = []; // stack
        var P = {};
        var g = {};
        var d = {};
        var Q = new heap(function (a, b) {
          return d[a] - d[b];
        }); // queue

        // init dictionaries
        for (var _i = 0; _i < V.length; _i++) {
          var _vid = V[_i].id();
          P[_vid] = [];
          g[_vid] = 0;
          d[_vid] = Infinity;
        }
        g[sid] = 1; // sigma
        d[sid] = 0; // distance to s

        Q.push(sid);
        while (!Q.empty()) {
          var _v = Q.pop();
          S.push(_v);
          if (weighted) {
            for (var j = 0; j < A[_v].length; j++) {
              var w = A[_v][j];
              var vEle = cy.getElementById(_v);
              var edge = void 0;
              if (vEle.edgesTo(w).length > 0) {
                edge = vEle.edgesTo(w)[0];
              } else {
                edge = w.edgesTo(vEle)[0];
              }
              var edgeWeight = weight(edge);
              w = w.id();
              if (d[w] > d[_v] + edgeWeight) {
                d[w] = d[_v] + edgeWeight;
                if (Q.nodes.indexOf(w) < 0) {
                  //if w is not in Q
                  Q.push(w);
                } else {
                  // update position if w is in Q
                  Q.updateItem(w);
                }
                g[w] = 0;
                P[w] = [];
              }
              if (d[w] == d[_v] + edgeWeight) {
                g[w] = g[w] + g[_v];
                P[w].push(_v);
              }
            }
          } else {
            for (var _j = 0; _j < A[_v].length; _j++) {
              var _w = A[_v][_j].id();
              if (d[_w] == Infinity) {
                Q.push(_w);
                d[_w] = d[_v] + 1;
              }
              if (d[_w] == d[_v] + 1) {
                g[_w] = g[_w] + g[_v];
                P[_w].push(_v);
              }
            }
          }
        }
        var e = {};
        for (var _i2 = 0; _i2 < V.length; _i2++) {
          e[V[_i2].id()] = 0;
        }
        while (S.length > 0) {
          var _w2 = S.pop();
          for (var _j2 = 0; _j2 < P[_w2].length; _j2++) {
            var _v2 = P[_w2][_j2];
            e[_v2] = e[_v2] + g[_v2] / g[_w2] * (1 + e[_w2]);
          }
          if (_w2 != V[s].id()) {
            C.set(_w2, C.get(_w2) + e[_w2]);
          }
        }
      };
      for (var s = 0; s < V.length; s++) {
        _loop(s);
      }
      var ret = {
        betweenness: function betweenness(node) {
          var id = cy.collection(node).id();
          return C.get(id);
        },
        betweennessNormalized: function betweennessNormalized(node) {
          if (max == 0) {
            return 0;
          }
          var id = cy.collection(node).id();
          return C.get(id) / max;
        }
      };

      // alias
      ret.betweennessNormalised = ret.betweennessNormalized;
      return ret;
    } // betweennessCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$l.bc = elesfn$l.betweennessCentrality;

  // Implemented by Zoe Xi @zoexi for GSOC 2016

  /* eslint-disable no-unused-vars */
  var defaults$c = defaults$g({
    expandFactor: 2,
    // affects time of computation and cluster granularity to some extent: M * M
    inflateFactor: 2,
    // affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j)
    multFactor: 1,
    // optional self loops for each node. Use a neutral value to improve cluster computations.
    maxIterations: 20,
    // maximum number of iterations of the MCL algorithm in a single run
    attributes: [
    // attributes/features used to group nodes, ie. similarity values between nodes
    function (edge) {
      return 1;
    }]
  });
  /* eslint-enable */

  var setOptions$3 = function setOptions(options) {
    return defaults$c(options);
  };
  /* eslint-enable */

  var getSimilarity$1 = function getSimilarity(edge, attributes) {
    var total = 0;
    for (var i = 0; i < attributes.length; i++) {
      total += attributes[i](edge);
    }
    return total;
  };
  var addLoops = function addLoops(M, n, val) {
    for (var i = 0; i < n; i++) {
      M[i * n + i] = val;
    }
  };
  var normalize = function normalize(M, n) {
    var sum;
    for (var col = 0; col < n; col++) {
      sum = 0;
      for (var row = 0; row < n; row++) {
        sum += M[row * n + col];
      }
      for (var _row = 0; _row < n; _row++) {
        M[_row * n + col] = M[_row * n + col] / sum;
      }
    }
  };

  // TODO: blocked matrix multiplication?
  var mmult = function mmult(A, B, n) {
    var C = new Array(n * n);
    for (var i = 0; i < n; i++) {
      for (var j = 0; j < n; j++) {
        C[i * n + j] = 0;
      }
      for (var k = 0; k < n; k++) {
        for (var _j = 0; _j < n; _j++) {
          C[i * n + _j] += A[i * n + k] * B[k * n + _j];
        }
      }
    }
    return C;
  };
  var expand = function expand(M, n, expandFactor /** power **/) {
    var _M = M.slice(0);
    for (var p = 1; p < expandFactor; p++) {
      M = mmult(M, _M, n);
    }
    return M;
  };
  var inflate = function inflate(M, n, inflateFactor /** r **/) {
    var _M = new Array(n * n);

    // M(i,j) ^ inflatePower
    for (var i = 0; i < n * n; i++) {
      _M[i] = Math.pow(M[i], inflateFactor);
    }
    normalize(_M, n);
    return _M;
  };
  var hasConverged = function hasConverged(M, _M, n2, roundFactor) {
    // Check that both matrices have the same elements (i,j)
    for (var i = 0; i < n2; i++) {
      var v1 = Math.round(M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); // truncate to 'roundFactor' decimal places
      var v2 = Math.round(_M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor);
      if (v1 !== v2) {
        return false;
      }
    }
    return true;
  };
  var assign$2 = function assign(M, n, nodes, cy) {
    var clusters = [];
    for (var i = 0; i < n; i++) {
      var cluster = [];
      for (var j = 0; j < n; j++) {
        // Row-wise attractors and elements that they attract belong in same cluster
        if (Math.round(M[i * n + j] * 1000) / 1000 > 0) {
          cluster.push(nodes[j]);
        }
      }
      if (cluster.length !== 0) {
        clusters.push(cy.collection(cluster));
      }
    }
    return clusters;
  };
  var isDuplicate = function isDuplicate(c1, c2) {
    for (var i = 0; i < c1.length; i++) {
      if (!c2[i] || c1[i].id() !== c2[i].id()) {
        return false;
      }
    }
    return true;
  };
  var removeDuplicates = function removeDuplicates(clusters) {
    for (var i = 0; i < clusters.length; i++) {
      for (var j = 0; j < clusters.length; j++) {
        if (i != j && isDuplicate(clusters[i], clusters[j])) {
          clusters.splice(j, 1);
        }
      }
    }
    return clusters;
  };
  var markovClustering = function markovClustering(options) {
    var nodes = this.nodes();
    var edges = this.edges();
    var cy = this.cy();

    // Set parameters of algorithm:
    var opts = setOptions$3(options);

    // Map each node to its position in node array
    var id2position = {};
    for (var i = 0; i < nodes.length; i++) {
      id2position[nodes[i].id()] = i;
    }

    // Generate stochastic matrix M from input graph G (should be symmetric/undirected)
    var n = nodes.length,
      n2 = n * n;
    var M = new Array(n2),
      _M;
    for (var _i = 0; _i < n2; _i++) {
      M[_i] = 0;
    }
    for (var e = 0; e < edges.length; e++) {
      var edge = edges[e];
      var _i2 = id2position[edge.source().id()];
      var j = id2position[edge.target().id()];
      var sim = getSimilarity$1(edge, opts.attributes);
      M[_i2 * n + j] += sim; // G should be symmetric and undirected
      M[j * n + _i2] += sim;
    }

    // Begin Markov cluster algorithm

    // Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal
    addLoops(M, n, opts.multFactor);

    // Step 2: M = normalize( M );
    normalize(M, n);
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      isStillMoving = false;

      // Step 3:
      _M = expand(M, n, opts.expandFactor);

      // Step 4:
      M = inflate(_M, n, opts.inflateFactor);

      // Step 5: check to see if ~steady state has been reached
      if (!hasConverged(M, _M, n2, 4)) {
        isStillMoving = true;
      }
      iterations++;
    }

    // Build clusters from matrix
    var clusters = assign$2(M, n, nodes, cy);

    // Remove duplicate clusters due to symmetry of graph and M matrix
    clusters = removeDuplicates(clusters);
    return clusters;
  };
  var markovClustering$1 = {
    markovClustering: markovClustering,
    mcl: markovClustering
  };

  // Common distance metrics for clustering algorithms
  var identity = function identity(x) {
    return x;
  };
  var absDiff = function absDiff(p, q) {
    return Math.abs(q - p);
  };
  var addAbsDiff = function addAbsDiff(total, p, q) {
    return total + absDiff(p, q);
  };
  var addSquaredDiff = function addSquaredDiff(total, p, q) {
    return total + Math.pow(q - p, 2);
  };
  var sqrt = function sqrt(x) {
    return Math.sqrt(x);
  };
  var maxAbsDiff = function maxAbsDiff(currentMax, p, q) {
    return Math.max(currentMax, absDiff(p, q));
  };
  var getDistance = function getDistance(length, getP, getQ, init, visit) {
    var post = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : identity;
    var ret = init;
    var p, q;
    for (var dim = 0; dim < length; dim++) {
      p = getP(dim);
      q = getQ(dim);
      ret = visit(ret, p, q);
    }
    return post(ret);
  };
  var distances = {
    euclidean: function euclidean(length, getP, getQ) {
      if (length >= 2) {
        return getDistance(length, getP, getQ, 0, addSquaredDiff, sqrt);
      } else {
        // for single attr case, more efficient to avoid sqrt
        return getDistance(length, getP, getQ, 0, addAbsDiff);
      }
    },
    squaredEuclidean: function squaredEuclidean(length, getP, getQ) {
      return getDistance(length, getP, getQ, 0, addSquaredDiff);
    },
    manhattan: function manhattan(length, getP, getQ) {
      return getDistance(length, getP, getQ, 0, addAbsDiff);
    },
    max: function max(length, getP, getQ) {
      return getDistance(length, getP, getQ, -Infinity, maxAbsDiff);
    }
  };

  // in case the user accidentally doesn't use camel case
  distances['squared-euclidean'] = distances['squaredEuclidean'];
  distances['squaredeuclidean'] = distances['squaredEuclidean'];
  function clusteringDistance (method, length, getP, getQ, nodeP, nodeQ) {
    var impl;
    if (fn$6(method)) {
      impl = method;
    } else {
      impl = distances[method] || distances.euclidean;
    }
    if (length === 0 && fn$6(method)) {
      return impl(nodeP, nodeQ);
    } else {
      return impl(length, getP, getQ, nodeP, nodeQ);
    }
  }

  var defaults$b = defaults$g({
    k: 2,
    m: 2,
    sensitivityThreshold: 0.0001,
    distance: 'euclidean',
    maxIterations: 10,
    attributes: [],
    testMode: false,
    testCentroids: null
  });
  var setOptions$2 = function setOptions(options) {
    return defaults$b(options);
  };

  var getDist = function getDist(type, node, centroid, attributes, mode) {
    var noNodeP = mode !== 'kMedoids';
    var getP = noNodeP ? function (i) {
      return centroid[i];
    } : function (i) {
      return attributes[i](centroid);
    };
    var getQ = function getQ(i) {
      return attributes[i](node);
    };
    var nodeP = centroid;
    var nodeQ = node;
    return clusteringDistance(type, attributes.length, getP, getQ, nodeP, nodeQ);
  };
  var randomCentroids = function randomCentroids(nodes, k, attributes) {
    var ndim = attributes.length;
    var min = new Array(ndim);
    var max = new Array(ndim);
    var centroids = new Array(k);
    var centroid = null;

    // Find min, max values for each attribute dimension
    for (var i = 0; i < ndim; i++) {
      min[i] = nodes.min(attributes[i]).value;
      max[i] = nodes.max(attributes[i]).value;
    }

    // Build k centroids, each represented as an n-dim feature vector
    for (var c = 0; c < k; c++) {
      centroid = [];
      for (var _i = 0; _i < ndim; _i++) {
        centroid[_i] = Math.random() * (max[_i] - min[_i]) + min[_i]; // random initial value
      }

      centroids[c] = centroid;
    }
    return centroids;
  };
  var classify = function classify(node, centroids, distance, attributes, type) {
    var min = Infinity;
    var index = 0;
    for (var i = 0; i < centroids.length; i++) {
      var dist = getDist(distance, node, centroids[i], attributes, type);
      if (dist < min) {
        min = dist;
        index = i;
      }
    }
    return index;
  };
  var buildCluster = function buildCluster(centroid, nodes, assignment) {
    var cluster = [];
    var node = null;
    for (var n = 0; n < nodes.length; n++) {
      node = nodes[n];
      if (assignment[node.id()] === centroid) {
        //console.log("Node " + node.id() + " is associated with medoid #: " + m);
        cluster.push(node);
      }
    }
    return cluster;
  };
  var haveValuesConverged = function haveValuesConverged(v1, v2, sensitivityThreshold) {
    return Math.abs(v2 - v1) <= sensitivityThreshold;
  };
  var haveMatricesConverged = function haveMatricesConverged(v1, v2, sensitivityThreshold) {
    for (var i = 0; i < v1.length; i++) {
      for (var j = 0; j < v1[i].length; j++) {
        var diff = Math.abs(v1[i][j] - v2[i][j]);
        if (diff > sensitivityThreshold) {
          return false;
        }
      }
    }
    return true;
  };
  var seenBefore = function seenBefore(node, medoids, n) {
    for (var i = 0; i < n; i++) {
      if (node === medoids[i]) return true;
    }
    return false;
  };
  var randomMedoids = function randomMedoids(nodes, k) {
    var medoids = new Array(k);

    // For small data sets, the probability of medoid conflict is greater,
    // so we need to check to see if we've already seen or chose this node before.
    if (nodes.length < 50) {
      // Randomly select k medoids from the n nodes
      for (var i = 0; i < k; i++) {
        var node = nodes[Math.floor(Math.random() * nodes.length)];

        // If we've already chosen this node to be a medoid, don't choose it again (for small data sets).
        // Instead choose a different random node.
        while (seenBefore(node, medoids, i)) {
          node = nodes[Math.floor(Math.random() * nodes.length)];
        }
        medoids[i] = node;
      }
    } else {
      // Relatively large data set, so pretty safe to not check and just select random nodes
      for (var _i2 = 0; _i2 < k; _i2++) {
        medoids[_i2] = nodes[Math.floor(Math.random() * nodes.length)];
      }
    }
    return medoids;
  };
  var findCost = function findCost(potentialNewMedoid, cluster, attributes) {
    var cost = 0;
    for (var n = 0; n < cluster.length; n++) {
      cost += getDist('manhattan', cluster[n], potentialNewMedoid, attributes, 'kMedoids');
    }
    return cost;
  };
  var kMeans = function kMeans(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var node = null;

    // Set parameters of algorithm: # of clusters, distance metric, etc.
    var opts = setOptions$2(options);

    // Begin k-means algorithm
    var clusters = new Array(opts.k);
    var assignment = {};
    var centroids;

    // Step 1: Initialize centroid positions
    if (opts.testMode) {
      if (typeof opts.testCentroids === 'number') {
        // TODO: implement a seeded random number generator.
        opts.testCentroids;
        centroids = randomCentroids(nodes, opts.k, opts.attributes);
      } else if (_typeof(opts.testCentroids) === 'object') {
        centroids = opts.testCentroids;
      } else {
        centroids = randomCentroids(nodes, opts.k, opts.attributes);
      }
    } else {
      centroids = randomCentroids(nodes, opts.k, opts.attributes);
    }
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      // Step 2: Assign nodes to the nearest centroid
      for (var n = 0; n < nodes.length; n++) {
        node = nodes[n];
        // Determine which cluster this node belongs to: node id => cluster #
        assignment[node.id()] = classify(node, centroids, opts.distance, opts.attributes, 'kMeans');
      }

      // Step 3: For each of the k clusters, update its centroid
      isStillMoving = false;
      for (var c = 0; c < opts.k; c++) {
        // Get all nodes that belong to this cluster
        var cluster = buildCluster(c, nodes, assignment);
        if (cluster.length === 0) {
          // If cluster is empty, break out early & move to next cluster
          continue;
        }

        // Update centroids by calculating avg of all nodes within the cluster.
        var ndim = opts.attributes.length;
        var centroid = centroids[c]; // [ dim_1, dim_2, dim_3, ... , dim_n ]
        var newCentroid = new Array(ndim);
        var sum = new Array(ndim);
        for (var d = 0; d < ndim; d++) {
          sum[d] = 0.0;
          for (var i = 0; i < cluster.length; i++) {
            node = cluster[i];
            sum[d] += opts.attributes[d](node);
          }
          newCentroid[d] = sum[d] / cluster.length;

          // Check to see if algorithm has converged, i.e. when centroids no longer change
          if (!haveValuesConverged(newCentroid[d], centroid[d], opts.sensitivityThreshold)) {
            isStillMoving = true;
          }
        }
        centroids[c] = newCentroid;
        clusters[c] = cy.collection(cluster);
      }
      iterations++;
    }
    return clusters;
  };
  var kMedoids = function kMedoids(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var node = null;
    var opts = setOptions$2(options);

    // Begin k-medoids algorithm
    var clusters = new Array(opts.k);
    var medoids;
    var assignment = {};
    var curCost;
    var minCosts = new Array(opts.k); // minimum cost configuration for each cluster

    // Step 1: Initialize k medoids
    if (opts.testMode) {
      if (typeof opts.testCentroids === 'number') ; else if (_typeof(opts.testCentroids) === 'object') {
        medoids = opts.testCentroids;
      } else {
        medoids = randomMedoids(nodes, opts.k);
      }
    } else {
      medoids = randomMedoids(nodes, opts.k);
    }
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      // Step 2: Assign nodes to the nearest medoid
      for (var n = 0; n < nodes.length; n++) {
        node = nodes[n];
        // Determine which cluster this node belongs to: node id => cluster #
        assignment[node.id()] = classify(node, medoids, opts.distance, opts.attributes, 'kMedoids');
      }
      isStillMoving = false;
      // Step 3: For each medoid m, and for each node associated with mediod m,
      // select the node with the lowest configuration cost as new medoid.
      for (var m = 0; m < medoids.length; m++) {
        // Get all nodes that belong to this medoid
        var cluster = buildCluster(m, nodes, assignment);
        if (cluster.length === 0) {
          // If cluster is empty, break out early & move to next cluster
          continue;
        }
        minCosts[m] = findCost(medoids[m], cluster, opts.attributes); // original cost

        // Select different medoid if its configuration has the lowest cost
        for (var _n = 0; _n < cluster.length; _n++) {
          curCost = findCost(cluster[_n], cluster, opts.attributes);
          if (curCost < minCosts[m]) {
            minCosts[m] = curCost;
            medoids[m] = cluster[_n];
            isStillMoving = true;
          }
        }
        clusters[m] = cy.collection(cluster);
      }
      iterations++;
    }
    return clusters;
  };
  var updateCentroids = function updateCentroids(centroids, nodes, U, weight, opts) {
    var numerator, denominator;
    for (var n = 0; n < nodes.length; n++) {
      for (var c = 0; c < centroids.length; c++) {
        weight[n][c] = Math.pow(U[n][c], opts.m);
      }
    }
    for (var _c = 0; _c < centroids.length; _c++) {
      for (var dim = 0; dim < opts.attributes.length; dim++) {
        numerator = 0;
        denominator = 0;
        for (var _n2 = 0; _n2 < nodes.length; _n2++) {
          numerator += weight[_n2][_c] * opts.attributes[dim](nodes[_n2]);
          denominator += weight[_n2][_c];
        }
        centroids[_c][dim] = numerator / denominator;
      }
    }
  };
  var updateMembership = function updateMembership(U, _U, centroids, nodes, opts) {
    // Save previous step
    for (var i = 0; i < U.length; i++) {
      _U[i] = U[i].slice();
    }
    var sum, numerator, denominator;
    var pow = 2 / (opts.m - 1);
    for (var c = 0; c < centroids.length; c++) {
      for (var n = 0; n < nodes.length; n++) {
        sum = 0;
        for (var k = 0; k < centroids.length; k++) {
          // against all other centroids
          numerator = getDist(opts.distance, nodes[n], centroids[c], opts.attributes, 'cmeans');
          denominator = getDist(opts.distance, nodes[n], centroids[k], opts.attributes, 'cmeans');
          sum += Math.pow(numerator / denominator, pow);
        }
        U[n][c] = 1 / sum;
      }
    }
  };
  var assign$1 = function assign(nodes, U, opts, cy) {
    var clusters = new Array(opts.k);
    for (var c = 0; c < clusters.length; c++) {
      clusters[c] = [];
    }
    var max;
    var index;
    for (var n = 0; n < U.length; n++) {
      // for each node (U is N x C matrix)
      max = -Infinity;
      index = -1;
      // Determine which cluster the node is most likely to belong in
      for (var _c2 = 0; _c2 < U[0].length; _c2++) {
        if (U[n][_c2] > max) {
          max = U[n][_c2];
          index = _c2;
        }
      }
      clusters[index].push(nodes[n]);
    }

    // Turn every array into a collection of nodes
    for (var _c3 = 0; _c3 < clusters.length; _c3++) {
      clusters[_c3] = cy.collection(clusters[_c3]);
    }
    return clusters;
  };
  var fuzzyCMeans = function fuzzyCMeans(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var opts = setOptions$2(options);

    // Begin fuzzy c-means algorithm
    var clusters;
    var centroids;
    var U;
    var _U;
    var weight;

    // Step 1: Initialize letiables.
    _U = new Array(nodes.length);
    for (var i = 0; i < nodes.length; i++) {
      // N x C matrix
      _U[i] = new Array(opts.k);
    }
    U = new Array(nodes.length);
    for (var _i3 = 0; _i3 < nodes.length; _i3++) {
      // N x C matrix
      U[_i3] = new Array(opts.k);
    }
    for (var _i4 = 0; _i4 < nodes.length; _i4++) {
      var total = 0;
      for (var j = 0; j < opts.k; j++) {
        U[_i4][j] = Math.random();
        total += U[_i4][j];
      }
      for (var _j = 0; _j < opts.k; _j++) {
        U[_i4][_j] = U[_i4][_j] / total;
      }
    }
    centroids = new Array(opts.k);
    for (var _i5 = 0; _i5 < opts.k; _i5++) {
      centroids[_i5] = new Array(opts.attributes.length);
    }
    weight = new Array(nodes.length);
    for (var _i6 = 0; _i6 < nodes.length; _i6++) {
      // N x C matrix
      weight[_i6] = new Array(opts.k);
    }
    // end init FCM

    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      isStillMoving = false;

      // Step 2: Calculate the centroids for each step.
      updateCentroids(centroids, nodes, U, weight, opts);

      // Step 3: Update the partition matrix U.
      updateMembership(U, _U, centroids, nodes, opts);

      // Step 4: Check for convergence.
      if (!haveMatricesConverged(U, _U, opts.sensitivityThreshold)) {
        isStillMoving = true;
      }
      iterations++;
    }

    // Assign nodes to clusters with highest probability.
    clusters = assign$1(nodes, U, opts, cy);
    return {
      clusters: clusters,
      degreeOfMembership: U
    };
  };
  var kClustering = {
    kMeans: kMeans,
    kMedoids: kMedoids,
    fuzzyCMeans: fuzzyCMeans,
    fcm: fuzzyCMeans
  };

  // Implemented by Zoe Xi @zoexi for GSOC 2016
  var defaults$a = defaults$g({
    distance: 'euclidean',
    // distance metric to compare nodes
    linkage: 'min',
    // linkage criterion : how to determine the distance between clusters of nodes
    mode: 'threshold',
    // mode:'threshold' => clusters must be threshold distance apart
    threshold: Infinity,
    // the distance threshold
    // mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters
    addDendrogram: false,
    // whether to add the dendrogram to the graph for viz
    dendrogramDepth: 0,
    // depth at which dendrogram branches are merged into the returned clusters
    attributes: [] // array of attr functions
  });

  var linkageAliases = {
    'single': 'min',
    'complete': 'max'
  };
  var setOptions$1 = function setOptions(options) {
    var opts = defaults$a(options);
    var preferredAlias = linkageAliases[opts.linkage];
    if (preferredAlias != null) {
      opts.linkage = preferredAlias;
    }
    return opts;
  };
  var mergeClosest = function mergeClosest(clusters, index, dists, mins, opts) {
    // Find two closest clusters from cached mins
    var minKey = 0;
    var min = Infinity;
    var dist;
    var attrs = opts.attributes;
    var getDist = function getDist(n1, n2) {
      return clusteringDistance(opts.distance, attrs.length, function (i) {
        return attrs[i](n1);
      }, function (i) {
        return attrs[i](n2);
      }, n1, n2);
    };
    for (var i = 0; i < clusters.length; i++) {
      var key = clusters[i].key;
      var _dist = dists[key][mins[key]];
      if (_dist < min) {
        minKey = key;
        min = _dist;
      }
    }
    if (opts.mode === 'threshold' && min >= opts.threshold || opts.mode === 'dendrogram' && clusters.length === 1) {
      return false;
    }
    var c1 = index[minKey];
    var c2 = index[mins[minKey]];
    var merged;

    // Merge two closest clusters
    if (opts.mode === 'dendrogram') {
      merged = {
        left: c1,
        right: c2,
        key: c1.key
      };
    } else {
      merged = {
        value: c1.value.concat(c2.value),
        key: c1.key
      };
    }
    clusters[c1.index] = merged;
    clusters.splice(c2.index, 1);
    index[c1.key] = merged;

    // Update distances with new merged cluster
    for (var _i = 0; _i < clusters.length; _i++) {
      var cur = clusters[_i];
      if (c1.key === cur.key) {
        dist = Infinity;
      } else if (opts.linkage === 'min') {
        dist = dists[c1.key][cur.key];
        if (dists[c1.key][cur.key] > dists[c2.key][cur.key]) {
          dist = dists[c2.key][cur.key];
        }
      } else if (opts.linkage === 'max') {
        dist = dists[c1.key][cur.key];
        if (dists[c1.key][cur.key] < dists[c2.key][cur.key]) {
          dist = dists[c2.key][cur.key];
        }
      } else if (opts.linkage === 'mean') {
        dist = (dists[c1.key][cur.key] * c1.size + dists[c2.key][cur.key] * c2.size) / (c1.size + c2.size);
      } else {
        if (opts.mode === 'dendrogram') dist = getDist(cur.value, c1.value);else dist = getDist(cur.value[0], c1.value[0]);
      }
      dists[c1.key][cur.key] = dists[cur.key][c1.key] = dist; // distance matrix is symmetric
    }

    // Update cached mins
    for (var _i2 = 0; _i2 < clusters.length; _i2++) {
      var key1 = clusters[_i2].key;
      if (mins[key1] === c1.key || mins[key1] === c2.key) {
        var _min = key1;
        for (var j = 0; j < clusters.length; j++) {
          var key2 = clusters[j].key;
          if (dists[key1][key2] < dists[key1][_min]) {
            _min = key2;
          }
        }
        mins[key1] = _min;
      }
      clusters[_i2].index = _i2;
    }

    // Clean up meta data used for clustering
    c1.key = c2.key = c1.index = c2.index = null;
    return true;
  };
  var getAllChildren = function getAllChildren(root, arr, cy) {
    if (!root) return;
    if (root.value) {
      arr.push(root.value);
    } else {
      if (root.left) getAllChildren(root.left, arr);
      if (root.right) getAllChildren(root.right, arr);
    }
  };
  var buildDendrogram = function buildDendrogram(root, cy) {
    if (!root) return '';
    if (root.left && root.right) {
      var leftStr = buildDendrogram(root.left, cy);
      var rightStr = buildDendrogram(root.right, cy);
      var node = cy.add({
        group: 'nodes',
        data: {
          id: leftStr + ',' + rightStr
        }
      });
      cy.add({
        group: 'edges',
        data: {
          source: leftStr,
          target: node.id()
        }
      });
      cy.add({
        group: 'edges',
        data: {
          source: rightStr,
          target: node.id()
        }
      });
      return node.id();
    } else if (root.value) {
      return root.value.id();
    }
  };
  var buildClustersFromTree = function buildClustersFromTree(root, k, cy) {
    if (!root) return [];
    var left = [],
      right = [],
      leaves = [];
    if (k === 0) {
      // don't cut tree, simply return all nodes as 1 single cluster
      if (root.left) getAllChildren(root.left, left);
      if (root.right) getAllChildren(root.right, right);
      leaves = left.concat(right);
      return [cy.collection(leaves)];
    } else if (k === 1) {
      // cut at root

      if (root.value) {
        // leaf node
        return [cy.collection(root.value)];
      } else {
        if (root.left) getAllChildren(root.left, left);
        if (root.right) getAllChildren(root.right, right);
        return [cy.collection(left), cy.collection(right)];
      }
    } else {
      if (root.value) {
        return [cy.collection(root.value)];
      } else {
        if (root.left) left = buildClustersFromTree(root.left, k - 1, cy);
        if (root.right) right = buildClustersFromTree(root.right, k - 1, cy);
        return left.concat(right);
      }
    }
  };

  var hierarchicalClustering = function hierarchicalClustering(options) {
    var cy = this.cy();
    var nodes = this.nodes();

    // Set parameters of algorithm: linkage type, distance metric, etc.
    var opts = setOptions$1(options);
    var attrs = opts.attributes;
    var getDist = function getDist(n1, n2) {
      return clusteringDistance(opts.distance, attrs.length, function (i) {
        return attrs[i](n1);
      }, function (i) {
        return attrs[i](n2);
      }, n1, n2);
    };

    // Begin hierarchical algorithm
    var clusters = [];
    var dists = []; // distances between each pair of clusters
    var mins = []; // closest cluster for each cluster
    var index = []; // hash of all clusters by key

    // In agglomerative (bottom-up) clustering, each node starts as its own cluster
    for (var n = 0; n < nodes.length; n++) {
      var cluster = {
        value: opts.mode === 'dendrogram' ? nodes[n] : [nodes[n]],
        key: n,
        index: n
      };
      clusters[n] = cluster;
      index[n] = cluster;
      dists[n] = [];
      mins[n] = 0;
    }

    // Calculate the distance between each pair of clusters
    for (var i = 0; i < clusters.length; i++) {
      for (var j = 0; j <= i; j++) {
        var dist = void 0;
        if (opts.mode === 'dendrogram') {
          // modes store cluster values differently
          dist = i === j ? Infinity : getDist(clusters[i].value, clusters[j].value);
        } else {
          dist = i === j ? Infinity : getDist(clusters[i].value[0], clusters[j].value[0]);
        }
        dists[i][j] = dist;
        dists[j][i] = dist;
        if (dist < dists[i][mins[i]]) {
          mins[i] = j; // Cache mins: closest cluster to cluster i is cluster j
        }
      }
    }

    // Find the closest pair of clusters and merge them into a single cluster.
    // Update distances between new cluster and each of the old clusters, and loop until threshold reached.
    var merged = mergeClosest(clusters, index, dists, mins, opts);
    while (merged) {
      merged = mergeClosest(clusters, index, dists, mins, opts);
    }
    var retClusters;

    // Dendrogram mode builds the hierarchy and adds intermediary nodes + edges
    // in addition to returning the clusters.
    if (opts.mode === 'dendrogram') {
      retClusters = buildClustersFromTree(clusters[0], opts.dendrogramDepth, cy);
      if (opts.addDendrogram) buildDendrogram(clusters[0], cy);
    } else {
      // Regular mode simply returns the clusters

      retClusters = new Array(clusters.length);
      clusters.forEach(function (cluster, i) {
        // Clean up meta data used for clustering
        cluster.key = cluster.index = null;
        retClusters[i] = cy.collection(cluster.value);
      });
    }
    return retClusters;
  };
  var hierarchicalClustering$1 = {
    hierarchicalClustering: hierarchicalClustering,
    hca: hierarchicalClustering
  };

  // Implemented by Zoe Xi @zoexi for GSOC 2016
  var defaults$9 = defaults$g({
    distance: 'euclidean',
    // distance metric to compare attributes between two nodes
    preference: 'median',
    // suitability of a data point to serve as an exemplar
    damping: 0.8,
    // damping factor between [0.5, 1)
    maxIterations: 1000,
    // max number of iterations to run
    minIterations: 100,
    // min number of iterations to run in order for clustering to stop
    attributes: [// functions to quantify the similarity between any two points
      // e.g. node => node.data('weight')
    ]
  });
  var setOptions = function setOptions(options) {
    var dmp = options.damping;
    var pref = options.preference;
    if (!(0.5 <= dmp && dmp < 1)) {
      error("Damping must range on [0.5, 1).  Got: ".concat(dmp));
    }
    var validPrefs = ['median', 'mean', 'min', 'max'];
    if (!(validPrefs.some(function (v) {
      return v === pref;
    }) || number$1(pref))) {
      error("Preference must be one of [".concat(validPrefs.map(function (p) {
        return "'".concat(p, "'");
      }).join(', '), "] or a number.  Got: ").concat(pref));
    }
    return defaults$9(options);
  };

  var getSimilarity = function getSimilarity(type, n1, n2, attributes) {
    var attr = function attr(n, i) {
      return attributes[i](n);
    };

    // nb negative because similarity should have an inverse relationship to distance
    return -clusteringDistance(type, attributes.length, function (i) {
      return attr(n1, i);
    }, function (i) {
      return attr(n2, i);
    }, n1, n2);
  };
  var getPreference = function getPreference(S, preference) {
    // larger preference = greater # of clusters
    var p = null;
    if (preference === 'median') {
      p = median(S);
    } else if (preference === 'mean') {
      p = mean(S);
    } else if (preference === 'min') {
      p = min(S);
    } else if (preference === 'max') {
      p = max(S);
    } else {
      // Custom preference number, as set by user
      p = preference;
    }
    return p;
  };
  var findExemplars = function findExemplars(n, R, A) {
    var indices = [];
    for (var i = 0; i < n; i++) {
      if (R[i * n + i] + A[i * n + i] > 0) {
        indices.push(i);
      }
    }
    return indices;
  };
  var assignClusters = function assignClusters(n, S, exemplars) {
    var clusters = [];
    for (var i = 0; i < n; i++) {
      var index = -1;
      var max = -Infinity;
      for (var ei = 0; ei < exemplars.length; ei++) {
        var e = exemplars[ei];
        if (S[i * n + e] > max) {
          index = e;
          max = S[i * n + e];
        }
      }
      if (index > 0) {
        clusters.push(index);
      }
    }
    for (var _ei = 0; _ei < exemplars.length; _ei++) {
      clusters[exemplars[_ei]] = exemplars[_ei];
    }
    return clusters;
  };
  var assign = function assign(n, S, exemplars) {
    var clusters = assignClusters(n, S, exemplars);
    for (var ei = 0; ei < exemplars.length; ei++) {
      var ii = [];
      for (var c = 0; c < clusters.length; c++) {
        if (clusters[c] === exemplars[ei]) {
          ii.push(c);
        }
      }
      var maxI = -1;
      var maxSum = -Infinity;
      for (var i = 0; i < ii.length; i++) {
        var sum = 0;
        for (var j = 0; j < ii.length; j++) {
          sum += S[ii[j] * n + ii[i]];
        }
        if (sum > maxSum) {
          maxI = i;
          maxSum = sum;
        }
      }
      exemplars[ei] = ii[maxI];
    }
    clusters = assignClusters(n, S, exemplars);
    return clusters;
  };
  var affinityPropagation = function affinityPropagation(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var opts = setOptions(options);

    // Map each node to its position in node array
    var id2position = {};
    for (var i = 0; i < nodes.length; i++) {
      id2position[nodes[i].id()] = i;
    }

    // Begin affinity propagation algorithm

    var n; // number of data points
    var n2; // size of matrices
    var S; // similarity matrix (1D array)
    var p; // preference/suitability of a data point to serve as an exemplar
    var R; // responsibility matrix (1D array)
    var A; // availability matrix (1D array)

    n = nodes.length;
    n2 = n * n;

    // Initialize and build S similarity matrix
    S = new Array(n2);
    for (var _i = 0; _i < n2; _i++) {
      S[_i] = -Infinity; // for cases where two data points shouldn't be linked together
    }

    for (var _i2 = 0; _i2 < n; _i2++) {
      for (var j = 0; j < n; j++) {
        if (_i2 !== j) {
          S[_i2 * n + j] = getSimilarity(opts.distance, nodes[_i2], nodes[j], opts.attributes);
        }
      }
    }

    // Place preferences on the diagonal of S
    p = getPreference(S, opts.preference);
    for (var _i3 = 0; _i3 < n; _i3++) {
      S[_i3 * n + _i3] = p;
    }

    // Initialize R responsibility matrix
    R = new Array(n2);
    for (var _i4 = 0; _i4 < n2; _i4++) {
      R[_i4] = 0.0;
    }

    // Initialize A availability matrix
    A = new Array(n2);
    for (var _i5 = 0; _i5 < n2; _i5++) {
      A[_i5] = 0.0;
    }
    var old = new Array(n);
    var Rp = new Array(n);
    var se = new Array(n);
    for (var _i6 = 0; _i6 < n; _i6++) {
      old[_i6] = 0.0;
      Rp[_i6] = 0.0;
      se[_i6] = 0;
    }
    var e = new Array(n * opts.minIterations);
    for (var _i7 = 0; _i7 < e.length; _i7++) {
      e[_i7] = 0;
    }
    var iter;
    for (iter = 0; iter < opts.maxIterations; iter++) {
      // main algorithmic loop

      // Update R responsibility matrix
      for (var _i8 = 0; _i8 < n; _i8++) {
        var max = -Infinity,
          max2 = -Infinity,
          maxI = -1,
          AS = 0.0;
        for (var _j = 0; _j < n; _j++) {
          old[_j] = R[_i8 * n + _j];
          AS = A[_i8 * n + _j] + S[_i8 * n + _j];
          if (AS >= max) {
            max2 = max;
            max = AS;
            maxI = _j;
          } else if (AS > max2) {
            max2 = AS;
          }
        }
        for (var _j2 = 0; _j2 < n; _j2++) {
          R[_i8 * n + _j2] = (1 - opts.damping) * (S[_i8 * n + _j2] - max) + opts.damping * old[_j2];
        }
        R[_i8 * n + maxI] = (1 - opts.damping) * (S[_i8 * n + maxI] - max2) + opts.damping * old[maxI];
      }

      // Update A availability matrix
      for (var _i9 = 0; _i9 < n; _i9++) {
        var sum = 0;
        for (var _j3 = 0; _j3 < n; _j3++) {
          old[_j3] = A[_j3 * n + _i9];
          Rp[_j3] = Math.max(0, R[_j3 * n + _i9]);
          sum += Rp[_j3];
        }
        sum -= Rp[_i9];
        Rp[_i9] = R[_i9 * n + _i9];
        sum += Rp[_i9];
        for (var _j4 = 0; _j4 < n; _j4++) {
          A[_j4 * n + _i9] = (1 - opts.damping) * Math.min(0, sum - Rp[_j4]) + opts.damping * old[_j4];
        }
        A[_i9 * n + _i9] = (1 - opts.damping) * (sum - Rp[_i9]) + opts.damping * old[_i9];
      }

      // Check for convergence
      var K = 0;
      for (var _i10 = 0; _i10 < n; _i10++) {
        var E = A[_i10 * n + _i10] + R[_i10 * n + _i10] > 0 ? 1 : 0;
        e[iter % opts.minIterations * n + _i10] = E;
        K += E;
      }
      if (K > 0 && (iter >= opts.minIterations - 1 || iter == opts.maxIterations - 1)) {
        var _sum = 0;
        for (var _i11 = 0; _i11 < n; _i11++) {
          se[_i11] = 0;
          for (var _j5 = 0; _j5 < opts.minIterations; _j5++) {
            se[_i11] += e[_j5 * n + _i11];
          }
          if (se[_i11] === 0 || se[_i11] === opts.minIterations) {
            _sum++;
          }
        }
        if (_sum === n) {
          // then we have convergence
          break;
        }
      }
    }

    // Identify exemplars (cluster centers)
    var exemplarsIndices = findExemplars(n, R, A);

    // Assign nodes to clusters
    var clusterIndices = assign(n, S, exemplarsIndices);
    var clusters = {};
    for (var c = 0; c < exemplarsIndices.length; c++) {
      clusters[exemplarsIndices[c]] = [];
    }
    for (var _i12 = 0; _i12 < nodes.length; _i12++) {
      var pos = id2position[nodes[_i12].id()];
      var clusterIndex = clusterIndices[pos];
      if (clusterIndex != null) {
        // the node may have not been assigned a cluster if no valid attributes were specified
        clusters[clusterIndex].push(nodes[_i12]);
      }
    }
    var retClusters = new Array(exemplarsIndices.length);
    for (var _c = 0; _c < exemplarsIndices.length; _c++) {
      retClusters[_c] = cy.collection(clusters[exemplarsIndices[_c]]);
    }
    return retClusters;
  };
  var affinityPropagation$1 = {
    affinityPropagation: affinityPropagation,
    ap: affinityPropagation
  };

  var hierholzerDefaults = defaults$g({
    root: undefined,
    directed: false
  });
  var elesfn$k = {
    hierholzer: function hierholzer(options) {
      if (!plainObject(options)) {
        var args = arguments;
        options = {
          root: args[0],
          directed: args[1]
        };
      }
      var _hierholzerDefaults = hierholzerDefaults(options),
        root = _hierholzerDefaults.root,
        directed = _hierholzerDefaults.directed;
      var eles = this;
      var dflag = false;
      var oddIn;
      var oddOut;
      var startVertex;
      if (root) startVertex = string(root) ? this.filter(root)[0].id() : root[0].id();
      var nodes = {};
      var edges = {};
      if (directed) {
        eles.forEach(function (ele) {
          var id = ele.id();
          if (ele.isNode()) {
            var ind = ele.indegree(true);
            var outd = ele.outdegree(true);
            var d1 = ind - outd;
            var d2 = outd - ind;
            if (d1 == 1) {
              if (oddIn) dflag = true;else oddIn = id;
            } else if (d2 == 1) {
              if (oddOut) dflag = true;else oddOut = id;
            } else if (d2 > 1 || d1 > 1) {
              dflag = true;
            }
            nodes[id] = [];
            ele.outgoers().forEach(function (e) {
              if (e.isEdge()) nodes[id].push(e.id());
            });
          } else {
            edges[id] = [undefined, ele.target().id()];
          }
        });
      } else {
        eles.forEach(function (ele) {
          var id = ele.id();
          if (ele.isNode()) {
            var d = ele.degree(true);
            if (d % 2) {
              if (!oddIn) oddIn = id;else if (!oddOut) oddOut = id;else dflag = true;
            }
            nodes[id] = [];
            ele.connectedEdges().forEach(function (e) {
              return nodes[id].push(e.id());
            });
          } else {
            edges[id] = [ele.source().id(), ele.target().id()];
          }
        });
      }
      var result = {
        found: false,
        trail: undefined
      };
      if (dflag) return result;else if (oddOut && oddIn) {
        if (directed) {
          if (startVertex && oddOut != startVertex) {
            return result;
          }
          startVertex = oddOut;
        } else {
          if (startVertex && oddOut != startVertex && oddIn != startVertex) {
            return result;
          } else if (!startVertex) {
            startVertex = oddOut;
          }
        }
      } else {
        if (!startVertex) startVertex = eles[0].id();
      }
      var walk = function walk(v) {
        var currentNode = v;
        var subtour = [v];
        var adj, adjTail, adjHead;
        while (nodes[currentNode].length) {
          adj = nodes[currentNode].shift();
          adjTail = edges[adj][0];
          adjHead = edges[adj][1];
          if (currentNode != adjHead) {
            nodes[adjHead] = nodes[adjHead].filter(function (e) {
              return e != adj;
            });
            currentNode = adjHead;
          } else if (!directed && currentNode != adjTail) {
            nodes[adjTail] = nodes[adjTail].filter(function (e) {
              return e != adj;
            });
            currentNode = adjTail;
          }
          subtour.unshift(adj);
          subtour.unshift(currentNode);
        }
        return subtour;
      };
      var trail = [];
      var subtour = [];
      subtour = walk(startVertex);
      while (subtour.length != 1) {
        if (nodes[subtour[0]].length == 0) {
          trail.unshift(eles.getElementById(subtour.shift()));
          trail.unshift(eles.getElementById(subtour.shift()));
        } else {
          subtour = walk(subtour.shift()).concat(subtour);
        }
      }
      trail.unshift(eles.getElementById(subtour.shift())); // final node

      for (var d in nodes) {
        if (nodes[d].length) {
          return result;
        }
      }
      result.found = true;
      result.trail = this.spawn(trail, true);
      return result;
    }
  };

  var hopcroftTarjanBiconnected = function hopcroftTarjanBiconnected() {
    var eles = this;
    var nodes = {};
    var id = 0;
    var edgeCount = 0;
    var components = [];
    var stack = [];
    var visitedEdges = {};
    var buildComponent = function buildComponent(x, y) {
      var i = stack.length - 1;
      var cutset = [];
      var component = eles.spawn();
      while (stack[i].x != x || stack[i].y != y) {
        cutset.push(stack.pop().edge);
        i--;
      }
      cutset.push(stack.pop().edge);
      cutset.forEach(function (edge) {
        var connectedNodes = edge.connectedNodes().intersection(eles);
        component.merge(edge);
        connectedNodes.forEach(function (node) {
          var nodeId = node.id();
          var connectedEdges = node.connectedEdges().intersection(eles);
          component.merge(node);
          if (!nodes[nodeId].cutVertex) {
            component.merge(connectedEdges);
          } else {
            component.merge(connectedEdges.filter(function (edge) {
              return edge.isLoop();
            }));
          }
        });
      });
      components.push(component);
    };
    var biconnectedSearch = function biconnectedSearch(root, currentNode, parent) {
      if (root === parent) edgeCount += 1;
      nodes[currentNode] = {
        id: id,
        low: id++,
        cutVertex: false
      };
      var edges = eles.getElementById(currentNode).connectedEdges().intersection(eles);
      if (edges.size() === 0) {
        components.push(eles.spawn(eles.getElementById(currentNode)));
      } else {
        var sourceId, targetId, otherNodeId, edgeId;
        edges.forEach(function (edge) {
          sourceId = edge.source().id();
          targetId = edge.target().id();
          otherNodeId = sourceId === currentNode ? targetId : sourceId;
          if (otherNodeId !== parent) {
            edgeId = edge.id();
            if (!visitedEdges[edgeId]) {
              visitedEdges[edgeId] = true;
              stack.push({
                x: currentNode,
                y: otherNodeId,
                edge: edge
              });
            }
            if (!(otherNodeId in nodes)) {
              biconnectedSearch(root, otherNodeId, currentNode);
              nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].low);
              if (nodes[currentNode].id <= nodes[otherNodeId].low) {
                nodes[currentNode].cutVertex = true;
                buildComponent(currentNode, otherNodeId);
              }
            } else {
              nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].id);
            }
          }
        });
      }
    };
    eles.forEach(function (ele) {
      if (ele.isNode()) {
        var nodeId = ele.id();
        if (!(nodeId in nodes)) {
          edgeCount = 0;
          biconnectedSearch(nodeId, nodeId);
          nodes[nodeId].cutVertex = edgeCount > 1;
        }
      }
    });
    var cutVertices = Object.keys(nodes).filter(function (id) {
      return nodes[id].cutVertex;
    }).map(function (id) {
      return eles.getElementById(id);
    });
    return {
      cut: eles.spawn(cutVertices),
      components: components
    };
  };
  var hopcroftTarjanBiconnected$1 = {
    hopcroftTarjanBiconnected: hopcroftTarjanBiconnected,
    htbc: hopcroftTarjanBiconnected,
    htb: hopcroftTarjanBiconnected,
    hopcroftTarjanBiconnectedComponents: hopcroftTarjanBiconnected
  };

  var tarjanStronglyConnected = function tarjanStronglyConnected() {
    var eles = this;
    var nodes = {};
    var index = 0;
    var components = [];
    var stack = [];
    var cut = eles.spawn(eles);
    var stronglyConnectedSearch = function stronglyConnectedSearch(sourceNodeId) {
      stack.push(sourceNodeId);
      nodes[sourceNodeId] = {
        index: index,
        low: index++,
        explored: false
      };
      var connectedEdges = eles.getElementById(sourceNodeId).connectedEdges().intersection(eles);
      connectedEdges.forEach(function (edge) {
        var targetNodeId = edge.target().id();
        if (targetNodeId !== sourceNodeId) {
          if (!(targetNodeId in nodes)) {
            stronglyConnectedSearch(targetNodeId);
          }
          if (!nodes[targetNodeId].explored) {
            nodes[sourceNodeId].low = Math.min(nodes[sourceNodeId].low, nodes[targetNodeId].low);
          }
        }
      });
      if (nodes[sourceNodeId].index === nodes[sourceNodeId].low) {
        var componentNodes = eles.spawn();
        for (;;) {
          var nodeId = stack.pop();
          componentNodes.merge(eles.getElementById(nodeId));
          nodes[nodeId].low = nodes[sourceNodeId].index;
          nodes[nodeId].explored = true;
          if (nodeId === sourceNodeId) {
            break;
          }
        }
        var componentEdges = componentNodes.edgesWith(componentNodes);
        var component = componentNodes.merge(componentEdges);
        components.push(component);
        cut = cut.difference(component);
      }
    };
    eles.forEach(function (ele) {
      if (ele.isNode()) {
        var nodeId = ele.id();
        if (!(nodeId in nodes)) {
          stronglyConnectedSearch(nodeId);
        }
      }
    });
    return {
      cut: cut,
      components: components
    };
  };
  var tarjanStronglyConnected$1 = {
    tarjanStronglyConnected: tarjanStronglyConnected,
    tsc: tarjanStronglyConnected,
    tscc: tarjanStronglyConnected,
    tarjanStronglyConnectedComponents: tarjanStronglyConnected
  };

  var elesfn$j = {};
  [elesfn$v, elesfn$u, elesfn$t, elesfn$s, elesfn$r, elesfn$q, elesfn$p, elesfn$o, elesfn$n, elesfn$m, elesfn$l, markovClustering$1, kClustering, hierarchicalClustering$1, affinityPropagation$1, elesfn$k, hopcroftTarjanBiconnected$1, tarjanStronglyConnected$1].forEach(function (props) {
    extend(elesfn$j, props);
  });

  /*!
  Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
  Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)
  Licensed under The MIT License (http://opensource.org/licenses/MIT)
  */

  /*  promise states [Promises/A+ 2.1]  */
  var STATE_PENDING = 0; /*  [Promises/A+ 2.1.1]  */
  var STATE_FULFILLED = 1; /*  [Promises/A+ 2.1.2]  */
  var STATE_REJECTED = 2; /*  [Promises/A+ 2.1.3]  */

  /*  promise object constructor  */
  var api = function api(executor) {
    /*  optionally support non-constructor/plain-function call  */
    if (!(this instanceof api)) return new api(executor);

    /*  initialize object  */
    this.id = 'Thenable/1.0.7';
    this.state = STATE_PENDING; /*  initial state  */
    this.fulfillValue = undefined; /*  initial value  */ /*  [Promises/A+ 1.3, 2.1.2.2]  */
    this.rejectReason = undefined; /*  initial reason */ /*  [Promises/A+ 1.5, 2.1.3.2]  */
    this.onFulfilled = []; /*  initial handlers  */
    this.onRejected = []; /*  initial handlers  */

    /*  provide optional information-hiding proxy  */
    this.proxy = {
      then: this.then.bind(this)
    };

    /*  support optional executor function  */
    if (typeof executor === 'function') executor.call(this, this.fulfill.bind(this), this.reject.bind(this));
  };

  /*  promise API methods  */
  api.prototype = {
    /*  promise resolving methods  */
    fulfill: function fulfill(value) {
      return deliver(this, STATE_FULFILLED, 'fulfillValue', value);
    },
    reject: function reject(value) {
      return deliver(this, STATE_REJECTED, 'rejectReason', value);
    },
    /*  "The then Method" [Promises/A+ 1.1, 1.2, 2.2]  */
    then: function then(onFulfilled, onRejected) {
      var curr = this;
      var next = new api(); /*  [Promises/A+ 2.2.7]  */
      curr.onFulfilled.push(resolver(onFulfilled, next, 'fulfill')); /*  [Promises/A+ 2.2.2/2.2.6]  */
      curr.onRejected.push(resolver(onRejected, next, 'reject')); /*  [Promises/A+ 2.2.3/2.2.6]  */
      execute(curr);
      return next.proxy; /*  [Promises/A+ 2.2.7, 3.3]  */
    }
  };

  /*  deliver an action  */
  var deliver = function deliver(curr, state, name, value) {
    if (curr.state === STATE_PENDING) {
      curr.state = state; /*  [Promises/A+ 2.1.2.1, 2.1.3.1]  */
      curr[name] = value; /*  [Promises/A+ 2.1.2.2, 2.1.3.2]  */
      execute(curr);
    }
    return curr;
  };

  /*  execute all handlers  */
  var execute = function execute(curr) {
    if (curr.state === STATE_FULFILLED) execute_handlers(curr, 'onFulfilled', curr.fulfillValue);else if (curr.state === STATE_REJECTED) execute_handlers(curr, 'onRejected', curr.rejectReason);
  };

  /*  execute particular set of handlers  */
  var execute_handlers = function execute_handlers(curr, name, value) {
    /* global setImmediate: true */
    /* global setTimeout: true */

    /*  short-circuit processing  */
    if (curr[name].length === 0) return;

    /*  iterate over all handlers, exactly once  */
    var handlers = curr[name];
    curr[name] = []; /*  [Promises/A+ 2.2.2.3, 2.2.3.3]  */
    var func = function func() {
      for (var i = 0; i < handlers.length; i++) {
        handlers[i](value);
      } /*  [Promises/A+ 2.2.5]  */
    };

    /*  execute procedure asynchronously  */ /*  [Promises/A+ 2.2.4, 3.1]  */
    if (typeof setImmediate === 'function') setImmediate(func);else setTimeout(func, 0);
  };

  /*  generate a resolver function  */
  var resolver = function resolver(cb, next, method) {
    return function (value) {
      if (typeof cb !== 'function') /*  [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4]  */
        next[method].call(next, value); /*  [Promises/A+ 2.2.7.3, 2.2.7.4]  */else {
        var result;
        try {
          result = cb(value);
        } /*  [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2]  */ catch (e) {
          next.reject(e); /*  [Promises/A+ 2.2.7.2]  */
          return;
        }
        resolve(next, result); /*  [Promises/A+ 2.2.7.1]  */
      }
    };
  };

  /*  "Promise Resolution Procedure"  */ /*  [Promises/A+ 2.3]  */
  var resolve = function resolve(promise, x) {
    /*  sanity check arguments  */ /*  [Promises/A+ 2.3.1]  */
    if (promise === x || promise.proxy === x) {
      promise.reject(new TypeError('cannot resolve promise with itself'));
      return;
    }

    /*  surgically check for a "then" method
      (mainly to just call the "getter" of "then" only once)  */
    var then;
    if (_typeof(x) === 'object' && x !== null || typeof x === 'function') {
      try {
        then = x.then;
      } /*  [Promises/A+ 2.3.3.1, 3.5]  */ catch (e) {
        promise.reject(e); /*  [Promises/A+ 2.3.3.2]  */
        return;
      }
    }

    /*  handle own Thenables    [Promises/A+ 2.3.2]
      and similar "thenables" [Promises/A+ 2.3.3]  */
    if (typeof then === 'function') {
      var resolved = false;
      try {
        /*  call retrieved "then" method */ /*  [Promises/A+ 2.3.3.3]  */
        then.call(x, /*  resolvePromise  */ /*  [Promises/A+ 2.3.3.3.1]  */
        function (y) {
          if (resolved) return;
          resolved = true; /*  [Promises/A+ 2.3.3.3.3]  */
          if (y === x) /*  [Promises/A+ 3.6]  */
            promise.reject(new TypeError('circular thenable chain'));else resolve(promise, y);
        }, /*  rejectPromise  */ /*  [Promises/A+ 2.3.3.3.2]  */
        function (r) {
          if (resolved) return;
          resolved = true; /*  [Promises/A+ 2.3.3.3.3]  */
          promise.reject(r);
        });
      } catch (e) {
        if (!resolved) /*  [Promises/A+ 2.3.3.3.3]  */
          promise.reject(e); /*  [Promises/A+ 2.3.3.3.4]  */
      }

      return;
    }

    /*  handle other values  */
    promise.fulfill(x); /*  [Promises/A+ 2.3.4, 2.3.3.4]  */
  };

  // so we always have Promise.all()
  api.all = function (ps) {
    return new api(function (resolveAll, rejectAll) {
      var vals = new Array(ps.length);
      var doneCount = 0;
      var fulfill = function fulfill(i, val) {
        vals[i] = val;
        doneCount++;
        if (doneCount === ps.length) {
          resolveAll(vals);
        }
      };
      for (var i = 0; i < ps.length; i++) {
        (function (i) {
          var p = ps[i];
          var isPromise = p != null && p.then != null;
          if (isPromise) {
            p.then(function (val) {
              fulfill(i, val);
            }, function (err) {
              rejectAll(err);
            });
          } else {
            var val = p;
            fulfill(i, val);
          }
        })(i);
      }
    });
  };
  api.resolve = function (val) {
    return new api(function (resolve, reject) {
      resolve(val);
    });
  };
  api.reject = function (val) {
    return new api(function (resolve, reject) {
      reject(val);
    });
  };
  var Promise$1 = typeof Promise !== 'undefined' ? Promise : api; // eslint-disable-line no-undef

  var Animation = function Animation(target, opts, opts2) {
    var isCore = core(target);
    var isEle = !isCore;
    var _p = this._private = extend({
      duration: 1000
    }, opts, opts2);
    _p.target = target;
    _p.style = _p.style || _p.css;
    _p.started = false;
    _p.playing = false;
    _p.hooked = false;
    _p.applying = false;
    _p.progress = 0;
    _p.completes = [];
    _p.frames = [];
    if (_p.complete && fn$6(_p.complete)) {
      _p.completes.push(_p.complete);
    }
    if (isEle) {
      var pos = target.position();
      _p.startPosition = _p.startPosition || {
        x: pos.x,
        y: pos.y
      };
      _p.startStyle = _p.startStyle || target.cy().style().getAnimationStartStyle(target, _p.style);
    }
    if (isCore) {
      var pan = target.pan();
      _p.startPan = {
        x: pan.x,
        y: pan.y
      };
      _p.startZoom = target.zoom();
    }

    // for future timeline/animations impl
    this.length = 1;
    this[0] = this;
  };
  var anifn = Animation.prototype;
  extend(anifn, {
    instanceString: function instanceString() {
      return 'animation';
    },
    hook: function hook() {
      var _p = this._private;
      if (!_p.hooked) {
        // add to target's animation queue
        var q;
        var tAni = _p.target._private.animation;
        if (_p.queue) {
          q = tAni.queue;
        } else {
          q = tAni.current;
        }
        q.push(this);

        // add to the animation loop pool
        if (elementOrCollection(_p.target)) {
          _p.target.cy().addToAnimationPool(_p.target);
        }
        _p.hooked = true;
      }
      return this;
    },
    play: function play() {
      var _p = this._private;

      // autorewind
      if (_p.progress === 1) {
        _p.progress = 0;
      }
      _p.playing = true;
      _p.started = false; // needs to be started by animation loop
      _p.stopped = false;
      this.hook();

      // the animation loop will start the animation...

      return this;
    },
    playing: function playing() {
      return this._private.playing;
    },
    apply: function apply() {
      var _p = this._private;
      _p.applying = true;
      _p.started = false; // needs to be started by animation loop
      _p.stopped = false;
      this.hook();

      // the animation loop will apply the animation at this progress

      return this;
    },
    applying: function applying() {
      return this._private.applying;
    },
    pause: function pause() {
      var _p = this._private;
      _p.playing = false;
      _p.started = false;
      return this;
    },
    stop: function stop() {
      var _p = this._private;
      _p.playing = false;
      _p.started = false;
      _p.stopped = true; // to be removed from animation queues

      return this;
    },
    rewind: function rewind() {
      return this.progress(0);
    },
    fastforward: function fastforward() {
      return this.progress(1);
    },
    time: function time(t) {
      var _p = this._private;
      if (t === undefined) {
        return _p.progress * _p.duration;
      } else {
        return this.progress(t / _p.duration);
      }
    },
    progress: function progress(p) {
      var _p = this._private;
      var wasPlaying = _p.playing;
      if (p === undefined) {
        return _p.progress;
      } else {
        if (wasPlaying) {
          this.pause();
        }
        _p.progress = p;
        _p.started = false;
        if (wasPlaying) {
          this.play();
        }
      }
      return this;
    },
    completed: function completed() {
      return this._private.progress === 1;
    },
    reverse: function reverse() {
      var _p = this._private;
      var wasPlaying = _p.playing;
      if (wasPlaying) {
        this.pause();
      }
      _p.progress = 1 - _p.progress;
      _p.started = false;
      var swap = function swap(a, b) {
        var _pa = _p[a];
        if (_pa == null) {
          return;
        }
        _p[a] = _p[b];
        _p[b] = _pa;
      };
      swap('zoom', 'startZoom');
      swap('pan', 'startPan');
      swap('position', 'startPosition');

      // swap styles
      if (_p.style) {
        for (var i = 0; i < _p.style.length; i++) {
          var prop = _p.style[i];
          var name = prop.name;
          var startStyleProp = _p.startStyle[name];
          _p.startStyle[name] = prop;
          _p.style[i] = startStyleProp;
        }
      }
      if (wasPlaying) {
        this.play();
      }
      return this;
    },
    promise: function promise(type) {
      var _p = this._private;
      var arr;
      switch (type) {
        case 'frame':
          arr = _p.frames;
          break;
        default:
        case 'complete':
        case 'completed':
          arr = _p.completes;
      }
      return new Promise$1(function (resolve, reject) {
        arr.push(function () {
          resolve();
        });
      });
    }
  });
  anifn.complete = anifn.completed;
  anifn.run = anifn.play;
  anifn.running = anifn.playing;

  var define$3 = {
    animated: function animated() {
      return function animatedImpl() {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return false;
        }
        var ele = all[0];
        if (ele) {
          return ele._private.animation.current.length > 0;
        }
      };
    },
    // animated

    clearQueue: function clearQueue() {
      return function clearQueueImpl() {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          ele._private.animation.queue = [];
        }
        return this;
      };
    },
    // clearQueue

    delay: function delay() {
      return function delayImpl(time, complete) {
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        return this.animate({
          delay: time,
          duration: time,
          complete: complete
        });
      };
    },
    // delay

    delayAnimation: function delayAnimation() {
      return function delayAnimationImpl(time, complete) {
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        return this.animation({
          delay: time,
          duration: time,
          complete: complete
        });
      };
    },
    // delay

    animation: function animation() {
      return function animationImpl(properties, params) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        var isCore = !selfIsArrayLike;
        var isEles = !isCore;
        if (!cy.styleEnabled()) {
          return this;
        }
        var style = cy.style();
        properties = extend({}, properties, params);
        var propertiesEmpty = Object.keys(properties).length === 0;
        if (propertiesEmpty) {
          return new Animation(all[0], properties); // nothing to animate
        }

        if (properties.duration === undefined) {
          properties.duration = 400;
        }
        switch (properties.duration) {
          case 'slow':
            properties.duration = 600;
            break;
          case 'fast':
            properties.duration = 200;
            break;
        }
        if (isEles) {
          properties.style = style.getPropsList(properties.style || properties.css);
          properties.css = undefined;
        }
        if (isEles && properties.renderedPosition != null) {
          var rpos = properties.renderedPosition;
          var pan = cy.pan();
          var zoom = cy.zoom();
          properties.position = renderedToModelPosition(rpos, zoom, pan);
        }

        // override pan w/ panBy if set
        if (isCore && properties.panBy != null) {
          var panBy = properties.panBy;
          var cyPan = cy.pan();
          properties.pan = {
            x: cyPan.x + panBy.x,
            y: cyPan.y + panBy.y
          };
        }

        // override pan w/ center if set
        var center = properties.center || properties.centre;
        if (isCore && center != null) {
          var centerPan = cy.getCenterPan(center.eles, properties.zoom);
          if (centerPan != null) {
            properties.pan = centerPan;
          }
        }

        // override pan & zoom w/ fit if set
        if (isCore && properties.fit != null) {
          var fit = properties.fit;
          var fitVp = cy.getFitViewport(fit.eles || fit.boundingBox, fit.padding);
          if (fitVp != null) {
            properties.pan = fitVp.pan;
            properties.zoom = fitVp.zoom;
          }
        }

        // override zoom (& potentially pan) w/ zoom obj if set
        if (isCore && plainObject(properties.zoom)) {
          var vp = cy.getZoomedViewport(properties.zoom);
          if (vp != null) {
            if (vp.zoomed) {
              properties.zoom = vp.zoom;
            }
            if (vp.panned) {
              properties.pan = vp.pan;
            }
          } else {
            properties.zoom = null; // an inavalid zoom (e.g. no delta) gets automatically destroyed
          }
        }

        return new Animation(all[0], properties);
      };
    },
    // animate

    animate: function animate() {
      return function animateImpl(properties, params) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        if (params) {
          properties = extend({}, properties, params);
        }

        // manually hook and run the animation
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          var queue = ele.animated() && (properties.queue === undefined || properties.queue);
          var ani = ele.animation(properties, queue ? {
            queue: true
          } : undefined);
          ani.play();
        }
        return this; // chaining
      };
    },

    // animate

    stop: function stop() {
      return function stopImpl(clearQueue, jumpToEnd) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          var _p = ele._private;
          var anis = _p.animation.current;
          for (var j = 0; j < anis.length; j++) {
            var ani = anis[j];
            var ani_p = ani._private;
            if (jumpToEnd) {
              // next iteration of the animation loop, the animation
              // will go straight to the end and be removed
              ani_p.duration = 0;
            }
          }

          // clear the queue of future animations
          if (clearQueue) {
            _p.animation.queue = [];
          }
          if (!jumpToEnd) {
            _p.animation.current = [];
          }
        }

        // we have to notify (the animation loop doesn't do it for us on `stop`)
        cy.notify('draw');
        return this;
      };
    } // stop
  }; // define

  /**
   * Checks if `value` is classified as an `Array` object.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is an array, else `false`.
   * @example
   *
   * _.isArray([1, 2, 3]);
   * // => true
   *
   * _.isArray(document.body.children);
   * // => false
   *
   * _.isArray('abc');
   * // => false
   *
   * _.isArray(_.noop);
   * // => false
   */
  var isArray = Array.isArray;

  var isArray_1 = isArray;

  /** Used to match property names within property paths. */
  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
      reIsPlainProp = /^\w*$/;

  /**
   * Checks if `value` is a property name and not a property path.
   *
   * @private
   * @param {*} value The value to check.
   * @param {Object} [object] The object to query keys on.
   * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
   */
  function isKey(value, object) {
    if (isArray_1(value)) {
      return false;
    }
    var type = typeof value;
    if (type == 'number' || type == 'symbol' || type == 'boolean' ||
        value == null || isSymbol_1(value)) {
      return true;
    }
    return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
      (object != null && value in Object(object));
  }

  var _isKey = isKey;

  /** `Object#toString` result references. */
  var asyncTag = '[object AsyncFunction]',
      funcTag = '[object Function]',
      genTag = '[object GeneratorFunction]',
      proxyTag = '[object Proxy]';

  /**
   * Checks if `value` is classified as a `Function` object.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Lang
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a function, else `false`.
   * @example
   *
   * _.isFunction(_);
   * // => true
   *
   * _.isFunction(/abc/);
   * // => false
   */
  function isFunction(value) {
    if (!isObject_1(value)) {
      return false;
    }
    // The use of `Object#toString` avoids issues with the `typeof` operator
    // in Safari 9 which returns 'object' for typed arrays and other constructors.
    var tag = _baseGetTag(value);
    return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
  }

  var isFunction_1 = isFunction;

  /** Used to detect overreaching core-js shims. */
  var coreJsData = _root['__core-js_shared__'];

  var _coreJsData = coreJsData;

  /** Used to detect methods masquerading as native. */
  var maskSrcKey = (function() {
    var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
    return uid ? ('Symbol(src)_1.' + uid) : '';
  }());

  /**
   * Checks if `func` has its source masked.
   *
   * @private
   * @param {Function} func The function to check.
   * @returns {boolean} Returns `true` if `func` is masked, else `false`.
   */
  function isMasked(func) {
    return !!maskSrcKey && (maskSrcKey in func);
  }

  var _isMasked = isMasked;

  /** Used for built-in method references. */
  var funcProto$1 = Function.prototype;

  /** Used to resolve the decompiled source of functions. */
  var funcToString$1 = funcProto$1.toString;

  /**
   * Converts `func` to its source code.
   *
   * @private
   * @param {Function} func The function to convert.
   * @returns {string} Returns the source code.
   */
  function toSource(func) {
    if (func != null) {
      try {
        return funcToString$1.call(func);
      } catch (e) {}
      try {
        return (func + '');
      } catch (e) {}
    }
    return '';
  }

  var _toSource = toSource;

  /**
   * Used to match `RegExp`
   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
   */
  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

  /** Used to detect host constructors (Safari). */
  var reIsHostCtor = /^\[object .+?Constructor\]$/;

  /** Used for built-in method references. */
  var funcProto = Function.prototype,
      objectProto$3 = Object.prototype;

  /** Used to resolve the decompiled source of functions. */
  var funcToString = funcProto.toString;

  /** Used to check objects for own properties. */
  var hasOwnProperty$3 = objectProto$3.hasOwnProperty;

  /** Used to detect if a method is native. */
  var reIsNative = RegExp('^' +
    funcToString.call(hasOwnProperty$3).replace(reRegExpChar, '\\$&')
    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  );

  /**
   * The base implementation of `_.isNative` without bad shim checks.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is a native function,
   *  else `false`.
   */
  function baseIsNative(value) {
    if (!isObject_1(value) || _isMasked(value)) {
      return false;
    }
    var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
    return pattern.test(_toSource(value));
  }

  var _baseIsNative = baseIsNative;

  /**
   * Gets the value at `key` of `object`.
   *
   * @private
   * @param {Object} [object] The object to query.
   * @param {string} key The key of the property to get.
   * @returns {*} Returns the property value.
   */
  function getValue$1(object, key) {
    return object == null ? undefined : object[key];
  }

  var _getValue = getValue$1;

  /**
   * Gets the native function at `key` of `object`.
   *
   * @private
   * @param {Object} object The object to query.
   * @param {string} key The key of the method to get.
   * @returns {*} Returns the function if it's native, else `undefined`.
   */
  function getNative(object, key) {
    var value = _getValue(object, key);
    return _baseIsNative(value) ? value : undefined;
  }

  var _getNative = getNative;

  /* Built-in method references that are verified to be native. */
  var nativeCreate = _getNative(Object, 'create');

  var _nativeCreate = nativeCreate;

  /**
   * Removes all key-value entries from the hash.
   *
   * @private
   * @name clear
   * @memberOf Hash
   */
  function hashClear() {
    this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
    this.size = 0;
  }

  var _hashClear = hashClear;

  /**
   * Removes `key` and its value from the hash.
   *
   * @private
   * @name delete
   * @memberOf Hash
   * @param {Object} hash The hash to modify.
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function hashDelete(key) {
    var result = this.has(key) && delete this.__data__[key];
    this.size -= result ? 1 : 0;
    return result;
  }

  var _hashDelete = hashDelete;

  /** Used to stand-in for `undefined` hash values. */
  var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';

  /** Used for built-in method references. */
  var objectProto$2 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$2 = objectProto$2.hasOwnProperty;

  /**
   * Gets the hash value for `key`.
   *
   * @private
   * @name get
   * @memberOf Hash
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function hashGet(key) {
    var data = this.__data__;
    if (_nativeCreate) {
      var result = data[key];
      return result === HASH_UNDEFINED$1 ? undefined : result;
    }
    return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
  }

  var _hashGet = hashGet;

  /** Used for built-in method references. */
  var objectProto$1 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$1 = objectProto$1.hasOwnProperty;

  /**
   * Checks if a hash value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf Hash
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function hashHas(key) {
    var data = this.__data__;
    return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key);
  }

  var _hashHas = hashHas;

  /** Used to stand-in for `undefined` hash values. */
  var HASH_UNDEFINED = '__lodash_hash_undefined__';

  /**
   * Sets the hash `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf Hash
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the hash instance.
   */
  function hashSet(key, value) {
    var data = this.__data__;
    this.size += this.has(key) ? 0 : 1;
    data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
    return this;
  }

  var _hashSet = hashSet;

  /**
   * Creates a hash object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function Hash(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `Hash`.
  Hash.prototype.clear = _hashClear;
  Hash.prototype['delete'] = _hashDelete;
  Hash.prototype.get = _hashGet;
  Hash.prototype.has = _hashHas;
  Hash.prototype.set = _hashSet;

  var _Hash = Hash;

  /**
   * Removes all key-value entries from the list cache.
   *
   * @private
   * @name clear
   * @memberOf ListCache
   */
  function listCacheClear() {
    this.__data__ = [];
    this.size = 0;
  }

  var _listCacheClear = listCacheClear;

  /**
   * Performs a
   * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
   * comparison between two values to determine if they are equivalent.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to compare.
   * @param {*} other The other value to compare.
   * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
   * @example
   *
   * var object = { 'a': 1 };
   * var other = { 'a': 1 };
   *
   * _.eq(object, object);
   * // => true
   *
   * _.eq(object, other);
   * // => false
   *
   * _.eq('a', 'a');
   * // => true
   *
   * _.eq('a', Object('a'));
   * // => false
   *
   * _.eq(NaN, NaN);
   * // => true
   */
  function eq(value, other) {
    return value === other || (value !== value && other !== other);
  }

  var eq_1 = eq;

  /**
   * Gets the index at which the `key` is found in `array` of key-value pairs.
   *
   * @private
   * @param {Array} array The array to inspect.
   * @param {*} key The key to search for.
   * @returns {number} Returns the index of the matched value, else `-1`.
   */
  function assocIndexOf(array, key) {
    var length = array.length;
    while (length--) {
      if (eq_1(array[length][0], key)) {
        return length;
      }
    }
    return -1;
  }

  var _assocIndexOf = assocIndexOf;

  /** Used for built-in method references. */
  var arrayProto = Array.prototype;

  /** Built-in value references. */
  var splice = arrayProto.splice;

  /**
   * Removes `key` and its value from the list cache.
   *
   * @private
   * @name delete
   * @memberOf ListCache
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function listCacheDelete(key) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    if (index < 0) {
      return false;
    }
    var lastIndex = data.length - 1;
    if (index == lastIndex) {
      data.pop();
    } else {
      splice.call(data, index, 1);
    }
    --this.size;
    return true;
  }

  var _listCacheDelete = listCacheDelete;

  /**
   * Gets the list cache value for `key`.
   *
   * @private
   * @name get
   * @memberOf ListCache
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function listCacheGet(key) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    return index < 0 ? undefined : data[index][1];
  }

  var _listCacheGet = listCacheGet;

  /**
   * Checks if a list cache value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf ListCache
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function listCacheHas(key) {
    return _assocIndexOf(this.__data__, key) > -1;
  }

  var _listCacheHas = listCacheHas;

  /**
   * Sets the list cache `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf ListCache
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the list cache instance.
   */
  function listCacheSet(key, value) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    if (index < 0) {
      ++this.size;
      data.push([key, value]);
    } else {
      data[index][1] = value;
    }
    return this;
  }

  var _listCacheSet = listCacheSet;

  /**
   * Creates an list cache object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function ListCache(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `ListCache`.
  ListCache.prototype.clear = _listCacheClear;
  ListCache.prototype['delete'] = _listCacheDelete;
  ListCache.prototype.get = _listCacheGet;
  ListCache.prototype.has = _listCacheHas;
  ListCache.prototype.set = _listCacheSet;

  var _ListCache = ListCache;

  /* Built-in method references that are verified to be native. */
  var Map$1 = _getNative(_root, 'Map');

  var _Map = Map$1;

  /**
   * Removes all key-value entries from the map.
   *
   * @private
   * @name clear
   * @memberOf MapCache
   */
  function mapCacheClear() {
    this.size = 0;
    this.__data__ = {
      'hash': new _Hash,
      'map': new (_Map || _ListCache),
      'string': new _Hash
    };
  }

  var _mapCacheClear = mapCacheClear;

  /**
   * Checks if `value` is suitable for use as unique object key.
   *
   * @private
   * @param {*} value The value to check.
   * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
   */
  function isKeyable(value) {
    var type = typeof value;
    return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
      ? (value !== '__proto__')
      : (value === null);
  }

  var _isKeyable = isKeyable;

  /**
   * Gets the data for `map`.
   *
   * @private
   * @param {Object} map The map to query.
   * @param {string} key The reference key.
   * @returns {*} Returns the map data.
   */
  function getMapData(map, key) {
    var data = map.__data__;
    return _isKeyable(key)
      ? data[typeof key == 'string' ? 'string' : 'hash']
      : data.map;
  }

  var _getMapData = getMapData;

  /**
   * Removes `key` and its value from the map.
   *
   * @private
   * @name delete
   * @memberOf MapCache
   * @param {string} key The key of the value to remove.
   * @returns {boolean} Returns `true` if the entry was removed, else `false`.
   */
  function mapCacheDelete(key) {
    var result = _getMapData(this, key)['delete'](key);
    this.size -= result ? 1 : 0;
    return result;
  }

  var _mapCacheDelete = mapCacheDelete;

  /**
   * Gets the map value for `key`.
   *
   * @private
   * @name get
   * @memberOf MapCache
   * @param {string} key The key of the value to get.
   * @returns {*} Returns the entry value.
   */
  function mapCacheGet(key) {
    return _getMapData(this, key).get(key);
  }

  var _mapCacheGet = mapCacheGet;

  /**
   * Checks if a map value for `key` exists.
   *
   * @private
   * @name has
   * @memberOf MapCache
   * @param {string} key The key of the entry to check.
   * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
   */
  function mapCacheHas(key) {
    return _getMapData(this, key).has(key);
  }

  var _mapCacheHas = mapCacheHas;

  /**
   * Sets the map `key` to `value`.
   *
   * @private
   * @name set
   * @memberOf MapCache
   * @param {string} key The key of the value to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns the map cache instance.
   */
  function mapCacheSet(key, value) {
    var data = _getMapData(this, key),
        size = data.size;

    data.set(key, value);
    this.size += data.size == size ? 0 : 1;
    return this;
  }

  var _mapCacheSet = mapCacheSet;

  /**
   * Creates a map cache object to store key-value pairs.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function MapCache(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `MapCache`.
  MapCache.prototype.clear = _mapCacheClear;
  MapCache.prototype['delete'] = _mapCacheDelete;
  MapCache.prototype.get = _mapCacheGet;
  MapCache.prototype.has = _mapCacheHas;
  MapCache.prototype.set = _mapCacheSet;

  var _MapCache = MapCache;

  /** Error message constants. */
  var FUNC_ERROR_TEXT = 'Expected a function';

  /**
   * Creates a function that memoizes the result of `func`. If `resolver` is
   * provided, it determines the cache key for storing the result based on the
   * arguments provided to the memoized function. By default, the first argument
   * provided to the memoized function is used as the map cache key. The `func`
   * is invoked with the `this` binding of the memoized function.
   *
   * **Note:** The cache is exposed as the `cache` property on the memoized
   * function. Its creation may be customized by replacing the `_.memoize.Cache`
   * constructor with one whose instances implement the
   * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
   * method interface of `clear`, `delete`, `get`, `has`, and `set`.
   *
   * @static
   * @memberOf _
   * @since 0.1.0
   * @category Function
   * @param {Function} func The function to have its output memoized.
   * @param {Function} [resolver] The function to resolve the cache key.
   * @returns {Function} Returns the new memoized function.
   * @example
   *
   * var object = { 'a': 1, 'b': 2 };
   * var other = { 'c': 3, 'd': 4 };
   *
   * var values = _.memoize(_.values);
   * values(object);
   * // => [1, 2]
   *
   * values(other);
   * // => [3, 4]
   *
   * object.a = 2;
   * values(object);
   * // => [1, 2]
   *
   * // Modify the result cache.
   * values.cache.set(object, ['a', 'b']);
   * values(object);
   * // => ['a', 'b']
   *
   * // Replace `_.memoize.Cache`.
   * _.memoize.Cache = WeakMap;
   */
  function memoize(func, resolver) {
    if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    var memoized = function() {
      var args = arguments,
          key = resolver ? resolver.apply(this, args) : args[0],
          cache = memoized.cache;

      if (cache.has(key)) {
        return cache.get(key);
      }
      var result = func.apply(this, args);
      memoized.cache = cache.set(key, result) || cache;
      return result;
    };
    memoized.cache = new (memoize.Cache || _MapCache);
    return memoized;
  }

  // Expose `MapCache`.
  memoize.Cache = _MapCache;

  var memoize_1 = memoize;

  /** Used as the maximum memoize cache size. */
  var MAX_MEMOIZE_SIZE = 500;

  /**
   * A specialized version of `_.memoize` which clears the memoized function's
   * cache when it exceeds `MAX_MEMOIZE_SIZE`.
   *
   * @private
   * @param {Function} func The function to have its output memoized.
   * @returns {Function} Returns the new memoized function.
   */
  function memoizeCapped(func) {
    var result = memoize_1(func, function(key) {
      if (cache.size === MAX_MEMOIZE_SIZE) {
        cache.clear();
      }
      return key;
    });

    var cache = result.cache;
    return result;
  }

  var _memoizeCapped = memoizeCapped;

  /** Used to match property names within property paths. */
  var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;

  /** Used to match backslashes in property paths. */
  var reEscapeChar = /\\(\\)?/g;

  /**
   * Converts `string` to a property path array.
   *
   * @private
   * @param {string} string The string to convert.
   * @returns {Array} Returns the property path array.
   */
  var stringToPath = _memoizeCapped(function(string) {
    var result = [];
    if (string.charCodeAt(0) === 46 /* . */) {
      result.push('');
    }
    string.replace(rePropName, function(match, number, quote, subString) {
      result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
    });
    return result;
  });

  var _stringToPath = stringToPath;

  /**
   * A specialized version of `_.map` for arrays without support for iteratee
   * shorthands.
   *
   * @private
   * @param {Array} [array] The array to iterate over.
   * @param {Function} iteratee The function invoked per iteration.
   * @returns {Array} Returns the new mapped array.
   */
  function arrayMap(array, iteratee) {
    var index = -1,
        length = array == null ? 0 : array.length,
        result = Array(length);

    while (++index < length) {
      result[index] = iteratee(array[index], index, array);
    }
    return result;
  }

  var _arrayMap = arrayMap;

  /** Used as references for various `Number` constants. */
  var INFINITY$1 = 1 / 0;

  /** Used to convert symbols to primitives and strings. */
  var symbolProto = _Symbol ? _Symbol.prototype : undefined,
      symbolToString = symbolProto ? symbolProto.toString : undefined;

  /**
   * The base implementation of `_.toString` which doesn't convert nullish
   * values to empty strings.
   *
   * @private
   * @param {*} value The value to process.
   * @returns {string} Returns the string.
   */
  function baseToString(value) {
    // Exit early for strings to avoid a performance hit in some environments.
    if (typeof value == 'string') {
      return value;
    }
    if (isArray_1(value)) {
      // Recursively convert values (susceptible to call stack limits).
      return _arrayMap(value, baseToString) + '';
    }
    if (isSymbol_1(value)) {
      return symbolToString ? symbolToString.call(value) : '';
    }
    var result = (value + '');
    return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
  }

  var _baseToString = baseToString;

  /**
   * Converts `value` to a string. An empty string is returned for `null`
   * and `undefined` values. The sign of `-0` is preserved.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Lang
   * @param {*} value The value to convert.
   * @returns {string} Returns the converted string.
   * @example
   *
   * _.toString(null);
   * // => ''
   *
   * _.toString(-0);
   * // => '-0'
   *
   * _.toString([1, 2, 3]);
   * // => '1,2,3'
   */
  function toString$1(value) {
    return value == null ? '' : _baseToString(value);
  }

  var toString_1 = toString$1;

  /**
   * Casts `value` to a path array if it's not one.
   *
   * @private
   * @param {*} value The value to inspect.
   * @param {Object} [object] The object to query keys on.
   * @returns {Array} Returns the cast property path array.
   */
  function castPath(value, object) {
    if (isArray_1(value)) {
      return value;
    }
    return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
  }

  var _castPath = castPath;

  /** Used as references for various `Number` constants. */
  var INFINITY = 1 / 0;

  /**
   * Converts `value` to a string key if it's not a string or symbol.
   *
   * @private
   * @param {*} value The value to inspect.
   * @returns {string|symbol} Returns the key.
   */
  function toKey(value) {
    if (typeof value == 'string' || isSymbol_1(value)) {
      return value;
    }
    var result = (value + '');
    return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  }

  var _toKey = toKey;

  /**
   * The base implementation of `_.get` without support for default values.
   *
   * @private
   * @param {Object} object The object to query.
   * @param {Array|string} path The path of the property to get.
   * @returns {*} Returns the resolved value.
   */
  function baseGet(object, path) {
    path = _castPath(path, object);

    var index = 0,
        length = path.length;

    while (object != null && index < length) {
      object = object[_toKey(path[index++])];
    }
    return (index && index == length) ? object : undefined;
  }

  var _baseGet = baseGet;

  /**
   * Gets the value at `path` of `object`. If the resolved value is
   * `undefined`, the `defaultValue` is returned in its place.
   *
   * @static
   * @memberOf _
   * @since 3.7.0
   * @category Object
   * @param {Object} object The object to query.
   * @param {Array|string} path The path of the property to get.
   * @param {*} [defaultValue] The value returned for `undefined` resolved values.
   * @returns {*} Returns the resolved value.
   * @example
   *
   * var object = { 'a': [{ 'b': { 'c': 3 } }] };
   *
   * _.get(object, 'a[0].b.c');
   * // => 3
   *
   * _.get(object, ['a', '0', 'b', 'c']);
   * // => 3
   *
   * _.get(object, 'a.b.c', 'default');
   * // => 'default'
   */
  function get(object, path, defaultValue) {
    var result = object == null ? undefined : _baseGet(object, path);
    return result === undefined ? defaultValue : result;
  }

  var get_1 = get;

  var defineProperty = (function() {
    try {
      var func = _getNative(Object, 'defineProperty');
      func({}, '', {});
      return func;
    } catch (e) {}
  }());

  var _defineProperty = defineProperty;

  /**
   * The base implementation of `assignValue` and `assignMergeValue` without
   * value checks.
   *
   * @private
   * @param {Object} object The object to modify.
   * @param {string} key The key of the property to assign.
   * @param {*} value The value to assign.
   */
  function baseAssignValue(object, key, value) {
    if (key == '__proto__' && _defineProperty) {
      _defineProperty(object, key, {
        'configurable': true,
        'enumerable': true,
        'value': value,
        'writable': true
      });
    } else {
      object[key] = value;
    }
  }

  var _baseAssignValue = baseAssignValue;

  /** Used for built-in method references. */
  var objectProto = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty = objectProto.hasOwnProperty;

  /**
   * Assigns `value` to `key` of `object` if the existing value is not equivalent
   * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
   * for equality comparisons.
   *
   * @private
   * @param {Object} object The object to modify.
   * @param {string} key The key of the property to assign.
   * @param {*} value The value to assign.
   */
  function assignValue(object, key, value) {
    var objValue = object[key];
    if (!(hasOwnProperty.call(object, key) && eq_1(objValue, value)) ||
        (value === undefined && !(key in object))) {
      _baseAssignValue(object, key, value);
    }
  }

  var _assignValue = assignValue;

  /** Used as references for various `Number` constants. */
  var MAX_SAFE_INTEGER = 9007199254740991;

  /** Used to detect unsigned integer values. */
  var reIsUint = /^(?:0|[1-9]\d*)$/;

  /**
   * Checks if `value` is a valid array-like index.
   *
   * @private
   * @param {*} value The value to check.
   * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
   * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
   */
  function isIndex(value, length) {
    var type = typeof value;
    length = length == null ? MAX_SAFE_INTEGER : length;

    return !!length &&
      (type == 'number' ||
        (type != 'symbol' && reIsUint.test(value))) &&
          (value > -1 && value % 1 == 0 && value < length);
  }

  var _isIndex = isIndex;

  /**
   * The base implementation of `_.set`.
   *
   * @private
   * @param {Object} object The object to modify.
   * @param {Array|string} path The path of the property to set.
   * @param {*} value The value to set.
   * @param {Function} [customizer] The function to customize path creation.
   * @returns {Object} Returns `object`.
   */
  function baseSet(object, path, value, customizer) {
    if (!isObject_1(object)) {
      return object;
    }
    path = _castPath(path, object);

    var index = -1,
        length = path.length,
        lastIndex = length - 1,
        nested = object;

    while (nested != null && ++index < length) {
      var key = _toKey(path[index]),
          newValue = value;

      if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
        return object;
      }

      if (index != lastIndex) {
        var objValue = nested[key];
        newValue = customizer ? customizer(objValue, key, nested) : undefined;
        if (newValue === undefined) {
          newValue = isObject_1(objValue)
            ? objValue
            : (_isIndex(path[index + 1]) ? [] : {});
        }
      }
      _assignValue(nested, key, newValue);
      nested = nested[key];
    }
    return object;
  }

  var _baseSet = baseSet;

  /**
   * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
   * it's created. Arrays are created for missing index properties while objects
   * are created for all other missing properties. Use `_.setWith` to customize
   * `path` creation.
   *
   * **Note:** This method mutates `object`.
   *
   * @static
   * @memberOf _
   * @since 3.7.0
   * @category Object
   * @param {Object} object The object to modify.
   * @param {Array|string} path The path of the property to set.
   * @param {*} value The value to set.
   * @returns {Object} Returns `object`.
   * @example
   *
   * var object = { 'a': [{ 'b': { 'c': 3 } }] };
   *
   * _.set(object, 'a[0].b.c', 4);
   * console.log(object.a[0].b.c);
   * // => 4
   *
   * _.set(object, ['x', '0', 'y', 'z'], 5);
   * console.log(object.x[0].y.z);
   * // => 5
   */
  function set(object, path, value) {
    return object == null ? object : _baseSet(object, path, value);
  }

  var set_1 = set;

  /**
   * Copies the values of `source` to `array`.
   *
   * @private
   * @param {Array} source The array to copy values from.
   * @param {Array} [array=[]] The array to copy values to.
   * @returns {Array} Returns `array`.
   */
  function copyArray(source, array) {
    var index = -1,
        length = source.length;

    array || (array = Array(length));
    while (++index < length) {
      array[index] = source[index];
    }
    return array;
  }

  var _copyArray = copyArray;

  /**
   * Converts `value` to a property path array.
   *
   * @static
   * @memberOf _
   * @since 4.0.0
   * @category Util
   * @param {*} value The value to convert.
   * @returns {Array} Returns the new property path array.
   * @example
   *
   * _.toPath('a.b.c');
   * // => ['a', 'b', 'c']
   *
   * _.toPath('a[0].b.c');
   * // => ['a', '0', 'b', 'c']
   */
  function toPath(value) {
    if (isArray_1(value)) {
      return _arrayMap(value, _toKey);
    }
    return isSymbol_1(value) ? [value] : _copyArray(_stringToPath(toString_1(value)));
  }

  var toPath_1 = toPath;

  var define$2 = {
    // access data field
    data: function data(params) {
      var defaults = {
        field: 'data',
        bindingEvent: 'data',
        allowBinding: false,
        allowSetting: false,
        allowGetting: false,
        settingEvent: 'data',
        settingTriggersEvent: false,
        triggerFnName: 'trigger',
        immutableKeys: {},
        // key => true if immutable
        updateStyle: false,
        beforeGet: function beforeGet(self) {},
        beforeSet: function beforeSet(self, obj) {},
        onSet: function onSet(self) {},
        canSet: function canSet(self) {
          return true;
        }
      };
      params = extend({}, defaults, params);
      return function dataImpl(name, value) {
        var p = params;
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var single = selfIsArrayLike ? self[0] : self;

        // .data('foo', ...)
        if (string(name)) {
          // set or get property
          var isPathLike = name.indexOf('.') !== -1; // there might be a normal field with a dot 
          var path = isPathLike && toPath_1(name);

          // .data('foo')
          if (p.allowGetting && value === undefined) {
            // get

            var ret;
            if (single) {
              p.beforeGet(single);

              // check if it's path and a field with the same name doesn't exist
              if (path && single._private[p.field][name] === undefined) {
                ret = get_1(single._private[p.field], path);
              } else {
                ret = single._private[p.field][name];
              }
            }
            return ret;

            // .data('foo', 'bar')
          } else if (p.allowSetting && value !== undefined) {
            // set
            var valid = !p.immutableKeys[name];
            if (valid) {
              var change = _defineProperty$1({}, name, value);
              p.beforeSet(self, change);
              for (var i = 0, l = all.length; i < l; i++) {
                var ele = all[i];
                if (p.canSet(ele)) {
                  if (path && single._private[p.field][name] === undefined) {
                    set_1(ele._private[p.field], path, value);
                  } else {
                    ele._private[p.field][name] = value;
                  }
                }
              }

              // update mappers if asked
              if (p.updateStyle) {
                self.updateStyle();
              }

              // call onSet callback
              p.onSet(self);
              if (p.settingTriggersEvent) {
                self[p.triggerFnName](p.settingEvent);
              }
            }
          }

          // .data({ 'foo': 'bar' })
        } else if (p.allowSetting && plainObject(name)) {
          // extend
          var obj = name;
          var k, v;
          var keys = Object.keys(obj);
          p.beforeSet(self, obj);
          for (var _i = 0; _i < keys.length; _i++) {
            k = keys[_i];
            v = obj[k];
            var _valid = !p.immutableKeys[k];
            if (_valid) {
              for (var j = 0; j < all.length; j++) {
                var _ele = all[j];
                if (p.canSet(_ele)) {
                  _ele._private[p.field][k] = v;
                }
              }
            }
          }

          // update mappers if asked
          if (p.updateStyle) {
            self.updateStyle();
          }

          // call onSet callback
          p.onSet(self);
          if (p.settingTriggersEvent) {
            self[p.triggerFnName](p.settingEvent);
          }

          // .data(function(){ ... })
        } else if (p.allowBinding && fn$6(name)) {
          // bind to event
          var fn = name;
          self.on(p.bindingEvent, fn);

          // .data()
        } else if (p.allowGetting && name === undefined) {
          // get whole object
          var _ret;
          if (single) {
            p.beforeGet(single);
            _ret = single._private[p.field];
          }
          return _ret;
        }
        return self; // maintain chainability
      }; // function
    },

    // data

    // remove data field
    removeData: function removeData(params) {
      var defaults = {
        field: 'data',
        event: 'data',
        triggerFnName: 'trigger',
        triggerEvent: false,
        immutableKeys: {} // key => true if immutable
      };

      params = extend({}, defaults, params);
      return function removeDataImpl(names) {
        var p = params;
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like

        // .removeData('foo bar')
        if (string(names)) {
          // then get the list of keys, and delete them
          var keys = names.split(/\s+/);
          var l = keys.length;
          for (var i = 0; i < l; i++) {
            // delete each non-empty key
            var key = keys[i];
            if (emptyString(key)) {
              continue;
            }
            var valid = !p.immutableKeys[key]; // not valid if immutable
            if (valid) {
              for (var i_a = 0, l_a = all.length; i_a < l_a; i_a++) {
                all[i_a]._private[p.field][key] = undefined;
              }
            }
          }
          if (p.triggerEvent) {
            self[p.triggerFnName](p.event);
          }

          // .removeData()
        } else if (names === undefined) {
          // then delete all keys

          for (var _i_a = 0, _l_a = all.length; _i_a < _l_a; _i_a++) {
            var _privateFields = all[_i_a]._private[p.field];
            var _keys = Object.keys(_privateFields);
            for (var _i2 = 0; _i2 < _keys.length; _i2++) {
              var _key = _keys[_i2];
              var validKeyToDelete = !p.immutableKeys[_key];
              if (validKeyToDelete) {
                _privateFields[_key] = undefined;
              }
            }
          }
          if (p.triggerEvent) {
            self[p.triggerFnName](p.event);
          }
        }
        return self; // maintain chaining
      }; // function
    } // removeData
  }; // define

  var define$1 = {
    eventAliasesOn: function eventAliasesOn(proto) {
      var p = proto;
      p.addListener = p.listen = p.bind = p.on;
      p.unlisten = p.unbind = p.off = p.removeListener;
      p.trigger = p.emit;

      // this is just a wrapper alias of .on()
      p.pon = p.promiseOn = function (events, selector) {
        var self = this;
        var args = Array.prototype.slice.call(arguments, 0);
        return new Promise$1(function (resolve, reject) {
          var callback = function callback(e) {
            self.off.apply(self, offArgs);
            resolve(e);
          };
          var onArgs = args.concat([callback]);
          var offArgs = onArgs.concat([]);
          self.on.apply(self, onArgs);
        });
      };
    }
  }; // define

  // use this module to cherry pick functions into your prototype
  var define = {};
  [define$3, define$2, define$1].forEach(function (m) {
    extend(define, m);
  });

  var elesfn$i = {
    animate: define.animate(),
    animation: define.animation(),
    animated: define.animated(),
    clearQueue: define.clearQueue(),
    delay: define.delay(),
    delayAnimation: define.delayAnimation(),
    stop: define.stop()
  };

  var elesfn$h = {
    classes: function classes(_classes) {
      var self = this;
      if (_classes === undefined) {
        var ret = [];
        self[0]._private.classes.forEach(function (cls) {
          return ret.push(cls);
        });
        return ret;
      } else if (!array(_classes)) {
        // extract classes from string
        _classes = (_classes || '').match(/\S+/g) || [];
      }
      var changed = [];
      var classesSet = new Set$1(_classes);

      // check and update each ele
      for (var j = 0; j < self.length; j++) {
        var ele = self[j];
        var _p = ele._private;
        var eleClasses = _p.classes;
        var changedEle = false;

        // check if ele has all of the passed classes
        for (var i = 0; i < _classes.length; i++) {
          var cls = _classes[i];
          var eleHasClass = eleClasses.has(cls);
          if (!eleHasClass) {
            changedEle = true;
            break;
          }
        }

        // check if ele has classes outside of those passed
        if (!changedEle) {
          changedEle = eleClasses.size !== _classes.length;
        }
        if (changedEle) {
          _p.classes = classesSet;
          changed.push(ele);
        }
      }

      // trigger update style on those eles that had class changes
      if (changed.length > 0) {
        this.spawn(changed).updateStyle().emit('class');
      }
      return self;
    },
    addClass: function addClass(classes) {
      return this.toggleClass(classes, true);
    },
    hasClass: function hasClass(className) {
      var ele = this[0];
      return ele != null && ele._private.classes.has(className);
    },
    toggleClass: function toggleClass(classes, toggle) {
      if (!array(classes)) {
        // extract classes from string
        classes = classes.match(/\S+/g) || [];
      }
      var self = this;
      var toggleUndefd = toggle === undefined;
      var changed = []; // eles who had classes changed

      for (var i = 0, il = self.length; i < il; i++) {
        var ele = self[i];
        var eleClasses = ele._private.classes;
        var changedEle = false;
        for (var j = 0; j < classes.length; j++) {
          var cls = classes[j];
          var hasClass = eleClasses.has(cls);
          var changedNow = false;
          if (toggle || toggleUndefd && !hasClass) {
            eleClasses.add(cls);
            changedNow = true;
          } else if (!toggle || toggleUndefd && hasClass) {
            eleClasses["delete"](cls);
            changedNow = true;
          }
          if (!changedEle && changedNow) {
            changed.push(ele);
            changedEle = true;
          }
        } // for j classes
      } // for i eles

      // trigger update style on those eles that had class changes
      if (changed.length > 0) {
        this.spawn(changed).updateStyle().emit('class');
      }
      return self;
    },
    removeClass: function removeClass(classes) {
      return this.toggleClass(classes, false);
    },
    flashClass: function flashClass(classes, duration) {
      var self = this;
      if (duration == null) {
        duration = 250;
      } else if (duration === 0) {
        return self; // nothing to do really
      }

      self.addClass(classes);
      setTimeout(function () {
        self.removeClass(classes);
      }, duration);
      return self;
    }
  };
  elesfn$h.className = elesfn$h.classNames = elesfn$h.classes;

  // tokens in the query language
  var tokens = {
    metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]',
    // chars we need to escape in let names, etc
    comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=',
    // binary comparison op (used in data selectors)
    boolOp: '\\?|\\!|\\^',
    // boolean (unary) operators (used in data selectors)
    string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'",
    // string literals (used in data selectors) -- doublequotes | singlequotes
    number: number,
    // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123
    meta: 'degree|indegree|outdegree',
    // allowed metadata fields (i.e. allowed functions to use from Collection)
    separator: '\\s*,\\s*',
    // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass
    descendant: '\\s+',
    child: '\\s+>\\s+',
    subject: '\\$',
    group: 'node|edge|\\*',
    directedEdge: '\\s+->\\s+',
    undirectedEdge: '\\s+<->\\s+'
  };
  tokens.variable = '(?:[\\w-.]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name can have letters, numbers, dashes, and periods
  tokens.className = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a class name has the same rules as a variable except it can't have a '.' in the name
  tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
  tokens.id = tokens.variable; // an element id (follows variable conventions)

  (function () {
    var ops, op, i;

    // add @ variants to comparatorOp
    ops = tokens.comparatorOp.split('|');
    for (i = 0; i < ops.length; i++) {
      op = ops[i];
      tokens.comparatorOp += '|@' + op;
    }

    // add ! variants to comparatorOp
    ops = tokens.comparatorOp.split('|');
    for (i = 0; i < ops.length; i++) {
      op = ops[i];
      if (op.indexOf('!') >= 0) {
        continue;
      } // skip ops that explicitly contain !
      if (op === '=') {
        continue;
      } // skip = b/c != is explicitly defined

      tokens.comparatorOp += '|\\!' + op;
    }
  })();

  /**
   * Make a new query object
   *
   * @prop type {Type} The type enum (int) of the query
   * @prop checks List of checks to make against an ele to test for a match
   */
  var newQuery = function newQuery() {
    return {
      checks: []
    };
  };

  /**
   * A check type enum-like object.  Uses integer values for fast match() lookup.
   * The ordering does not matter as long as the ints are unique.
   */
  var Type = {
    /** E.g. node */
    GROUP: 0,
    /** A collection of elements */
    COLLECTION: 1,
    /** A filter(ele) function */
    FILTER: 2,
    /** E.g. [foo > 1] */
    DATA_COMPARE: 3,
    /** E.g. [foo] */
    DATA_EXIST: 4,
    /** E.g. [?foo] */
    DATA_BOOL: 5,
    /** E.g. [[degree > 2]] */
    META_COMPARE: 6,
    /** E.g. :selected */
    STATE: 7,
    /** E.g. #foo */
    ID: 8,
    /** E.g. .foo */
    CLASS: 9,
    /** E.g. #foo <-> #bar */
    UNDIRECTED_EDGE: 10,
    /** E.g. #foo -> #bar */
    DIRECTED_EDGE: 11,
    /** E.g. $#foo -> #bar */
    NODE_SOURCE: 12,
    /** E.g. #foo -> $#bar */
    NODE_TARGET: 13,
    /** E.g. $#foo <-> #bar */
    NODE_NEIGHBOR: 14,
    /** E.g. #foo > #bar */
    CHILD: 15,
    /** E.g. #foo #bar */
    DESCENDANT: 16,
    /** E.g. $#foo > #bar */
    PARENT: 17,
    /** E.g. $#foo #bar */
    ANCESTOR: 18,
    /** E.g. #foo > $bar > #baz */
    COMPOUND_SPLIT: 19,
    /** Always matches, useful placeholder for subject in `COMPOUND_SPLIT` */
    TRUE: 20
  };

  var stateSelectors = [{
    selector: ':selected',
    matches: function matches(ele) {
      return ele.selected();
    }
  }, {
    selector: ':unselected',
    matches: function matches(ele) {
      return !ele.selected();
    }
  }, {
    selector: ':selectable',
    matches: function matches(ele) {
      return ele.selectable();
    }
  }, {
    selector: ':unselectable',
    matches: function matches(ele) {
      return !ele.selectable();
    }
  }, {
    selector: ':locked',
    matches: function matches(ele) {
      return ele.locked();
    }
  }, {
    selector: ':unlocked',
    matches: function matches(ele) {
      return !ele.locked();
    }
  }, {
    selector: ':visible',
    matches: function matches(ele) {
      return ele.visible();
    }
  }, {
    selector: ':hidden',
    matches: function matches(ele) {
      return !ele.visible();
    }
  }, {
    selector: ':transparent',
    matches: function matches(ele) {
      return ele.transparent();
    }
  }, {
    selector: ':grabbed',
    matches: function matches(ele) {
      return ele.grabbed();
    }
  }, {
    selector: ':free',
    matches: function matches(ele) {
      return !ele.grabbed();
    }
  }, {
    selector: ':removed',
    matches: function matches(ele) {
      return ele.removed();
    }
  }, {
    selector: ':inside',
    matches: function matches(ele) {
      return !ele.removed();
    }
  }, {
    selector: ':grabbable',
    matches: function matches(ele) {
      return ele.grabbable();
    }
  }, {
    selector: ':ungrabbable',
    matches: function matches(ele) {
      return !ele.grabbable();
    }
  }, {
    selector: ':animated',
    matches: function matches(ele) {
      return ele.animated();
    }
  }, {
    selector: ':unanimated',
    matches: function matches(ele) {
      return !ele.animated();
    }
  }, {
    selector: ':parent',
    matches: function matches(ele) {
      return ele.isParent();
    }
  }, {
    selector: ':childless',
    matches: function matches(ele) {
      return ele.isChildless();
    }
  }, {
    selector: ':child',
    matches: function matches(ele) {
      return ele.isChild();
    }
  }, {
    selector: ':orphan',
    matches: function matches(ele) {
      return ele.isOrphan();
    }
  }, {
    selector: ':nonorphan',
    matches: function matches(ele) {
      return ele.isChild();
    }
  }, {
    selector: ':compound',
    matches: function matches(ele) {
      if (ele.isNode()) {
        return ele.isParent();
      } else {
        return ele.source().isParent() || ele.target().isParent();
      }
    }
  }, {
    selector: ':loop',
    matches: function matches(ele) {
      return ele.isLoop();
    }
  }, {
    selector: ':simple',
    matches: function matches(ele) {
      return ele.isSimple();
    }
  }, {
    selector: ':active',
    matches: function matches(ele) {
      return ele.active();
    }
  }, {
    selector: ':inactive',
    matches: function matches(ele) {
      return !ele.active();
    }
  }, {
    selector: ':backgrounding',
    matches: function matches(ele) {
      return ele.backgrounding();
    }
  }, {
    selector: ':nonbackgrounding',
    matches: function matches(ele) {
      return !ele.backgrounding();
    }
  }].sort(function (a, b) {
    // n.b. selectors that are starting substrings of others must have the longer ones first
    return descending(a.selector, b.selector);
  });
  var lookup = function () {
    var selToFn = {};
    var s;
    for (var i = 0; i < stateSelectors.length; i++) {
      s = stateSelectors[i];
      selToFn[s.selector] = s.matches;
    }
    return selToFn;
  }();
  var stateSelectorMatches = function stateSelectorMatches(sel, ele) {
    return lookup[sel](ele);
  };
  var stateSelectorRegex = '(' + stateSelectors.map(function (s) {
    return s.selector;
  }).join('|') + ')';

  // when a token like a variable has escaped meta characters, we need to clean the backslashes out
  // so that values get compared properly in Selector.filter()
  var cleanMetaChars = function cleanMetaChars(str) {
    return str.replace(new RegExp('\\\\(' + tokens.metaChar + ')', 'g'), function (match, $1) {
      return $1;
    });
  };
  var replaceLastQuery = function replaceLastQuery(selector, examiningQuery, replacementQuery) {
    selector[selector.length - 1] = replacementQuery;
  };

  // NOTE: add new expression syntax here to have it recognised by the parser;
  // - a query contains all adjacent (i.e. no separator in between) expressions;
  // - the current query is stored in selector[i]
  // - you need to check the query objects in match() for it actually filter properly, but that's pretty straight forward
  var exprs = [{
    name: 'group',
    // just used for identifying when debugging
    query: true,
    regex: '(' + tokens.group + ')',
    populate: function populate(selector, query, _ref) {
      var _ref2 = _slicedToArray(_ref, 1),
        group = _ref2[0];
      query.checks.push({
        type: Type.GROUP,
        value: group === '*' ? group : group + 's'
      });
    }
  }, {
    name: 'state',
    query: true,
    regex: stateSelectorRegex,
    populate: function populate(selector, query, _ref3) {
      var _ref4 = _slicedToArray(_ref3, 1),
        state = _ref4[0];
      query.checks.push({
        type: Type.STATE,
        value: state
      });
    }
  }, {
    name: 'id',
    query: true,
    regex: '\\#(' + tokens.id + ')',
    populate: function populate(selector, query, _ref5) {
      var _ref6 = _slicedToArray(_ref5, 1),
        id = _ref6[0];
      query.checks.push({
        type: Type.ID,
        value: cleanMetaChars(id)
      });
    }
  }, {
    name: 'className',
    query: true,
    regex: '\\.(' + tokens.className + ')',
    populate: function populate(selector, query, _ref7) {
      var _ref8 = _slicedToArray(_ref7, 1),
        className = _ref8[0];
      query.checks.push({
        type: Type.CLASS,
        value: cleanMetaChars(className)
      });
    }
  }, {
    name: 'dataExists',
    query: true,
    regex: '\\[\\s*(' + tokens.variable + ')\\s*\\]',
    populate: function populate(selector, query, _ref9) {
      var _ref10 = _slicedToArray(_ref9, 1),
        variable = _ref10[0];
      query.checks.push({
        type: Type.DATA_EXIST,
        field: cleanMetaChars(variable)
      });
    }
  }, {
    name: 'dataCompare',
    query: true,
    regex: '\\[\\s*(' + tokens.variable + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.value + ')\\s*\\]',
    populate: function populate(selector, query, _ref11) {
      var _ref12 = _slicedToArray(_ref11, 3),
        variable = _ref12[0],
        comparatorOp = _ref12[1],
        value = _ref12[2];
      var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null;
      if (valueIsString) {
        value = value.substring(1, value.length - 1);
      } else {
        value = parseFloat(value);
      }
      query.checks.push({
        type: Type.DATA_COMPARE,
        field: cleanMetaChars(variable),
        operator: comparatorOp,
        value: value
      });
    }
  }, {
    name: 'dataBool',
    query: true,
    regex: '\\[\\s*(' + tokens.boolOp + ')\\s*(' + tokens.variable + ')\\s*\\]',
    populate: function populate(selector, query, _ref13) {
      var _ref14 = _slicedToArray(_ref13, 2),
        boolOp = _ref14[0],
        variable = _ref14[1];
      query.checks.push({
        type: Type.DATA_BOOL,
        field: cleanMetaChars(variable),
        operator: boolOp
      });
    }
  }, {
    name: 'metaCompare',
    query: true,
    regex: '\\[\\[\\s*(' + tokens.meta + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.number + ')\\s*\\]\\]',
    populate: function populate(selector, query, _ref15) {
      var _ref16 = _slicedToArray(_ref15, 3),
        meta = _ref16[0],
        comparatorOp = _ref16[1],
        number = _ref16[2];
      query.checks.push({
        type: Type.META_COMPARE,
        field: cleanMetaChars(meta),
        operator: comparatorOp,
        value: parseFloat(number)
      });
    }
  }, {
    name: 'nextQuery',
    separator: true,
    regex: tokens.separator,
    populate: function populate(selector, query) {
      var currentSubject = selector.currentSubject;
      var edgeCount = selector.edgeCount;
      var compoundCount = selector.compoundCount;
      var lastQ = selector[selector.length - 1];
      if (currentSubject != null) {
        lastQ.subject = currentSubject;
        selector.currentSubject = null;
      }
      lastQ.edgeCount = edgeCount;
      lastQ.compoundCount = compoundCount;
      selector.edgeCount = 0;
      selector.compoundCount = 0;

      // go on to next query
      var nextQuery = selector[selector.length++] = newQuery();
      return nextQuery; // this is the new query to be filled by the following exprs
    }
  }, {
    name: 'directedEdge',
    separator: true,
    regex: tokens.directedEdge,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // undirected edge
        var edgeQuery = newQuery();
        var source = query;
        var target = newQuery();
        edgeQuery.checks.push({
          type: Type.DIRECTED_EDGE,
          source: source,
          target: target
        });

        // the query in the selector should be the edge rather than the source
        replaceLastQuery(selector, query, edgeQuery);
        selector.edgeCount++;

        // we're now populating the target query with expressions that follow
        return target;
      } else {
        // source/target
        var srcTgtQ = newQuery();
        var _source = query;
        var _target = newQuery();
        srcTgtQ.checks.push({
          type: Type.NODE_SOURCE,
          source: _source,
          target: _target
        });

        // the query in the selector should be the neighbourhood rather than the node
        replaceLastQuery(selector, query, srcTgtQ);
        selector.edgeCount++;
        return _target; // now populating the target with the following expressions
      }
    }
  }, {
    name: 'undirectedEdge',
    separator: true,
    regex: tokens.undirectedEdge,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // undirected edge
        var edgeQuery = newQuery();
        var source = query;
        var target = newQuery();
        edgeQuery.checks.push({
          type: Type.UNDIRECTED_EDGE,
          nodes: [source, target]
        });

        // the query in the selector should be the edge rather than the source
        replaceLastQuery(selector, query, edgeQuery);
        selector.edgeCount++;

        // we're now populating the target query with expressions that follow
        return target;
      } else {
        // neighbourhood
        var nhoodQ = newQuery();
        var node = query;
        var neighbor = newQuery();
        nhoodQ.checks.push({
          type: Type.NODE_NEIGHBOR,
          node: node,
          neighbor: neighbor
        });

        // the query in the selector should be the neighbourhood rather than the node
        replaceLastQuery(selector, query, nhoodQ);
        return neighbor; // now populating the neighbor with following expressions
      }
    }
  }, {
    name: 'child',
    separator: true,
    regex: tokens.child,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // default: child query
        var parentChildQuery = newQuery();
        var child = newQuery();
        var parent = selector[selector.length - 1];
        parentChildQuery.checks.push({
          type: Type.CHILD,
          parent: parent,
          child: child
        });

        // the query in the selector should be the '>' itself
        replaceLastQuery(selector, query, parentChildQuery);
        selector.compoundCount++;

        // we're now populating the child query with expressions that follow
        return child;
      } else if (selector.currentSubject === query) {
        // compound split query
        var compound = newQuery();
        var left = selector[selector.length - 1];
        var right = newQuery();
        var subject = newQuery();
        var _child = newQuery();
        var _parent = newQuery();

        // set up the root compound q
        compound.checks.push({
          type: Type.COMPOUND_SPLIT,
          left: left,
          right: right,
          subject: subject
        });

        // populate the subject and replace the q at the old spot (within left) with TRUE
        subject.checks = query.checks; // take the checks from the left
        query.checks = [{
          type: Type.TRUE
        }]; // checks under left refs the subject implicitly

        // set up the right q
        _parent.checks.push({
          type: Type.TRUE
        }); // parent implicitly refs the subject
        right.checks.push({
          type: Type.PARENT,
          // type is swapped on right side queries
          parent: _parent,
          child: _child // empty for now
        });

        replaceLastQuery(selector, left, compound);

        // update the ref since we moved things around for `query`
        selector.currentSubject = subject;
        selector.compoundCount++;
        return _child; // now populating the right side's child
      } else {
        // parent query
        // info for parent query
        var _parent2 = newQuery();
        var _child2 = newQuery();
        var pcQChecks = [{
          type: Type.PARENT,
          parent: _parent2,
          child: _child2
        }];

        // the parent-child query takes the place of the query previously being populated
        _parent2.checks = query.checks; // the previous query contains the checks for the parent
        query.checks = pcQChecks; // pc query takes over

        selector.compoundCount++;
        return _child2; // we're now populating the child
      }
    }
  }, {
    name: 'descendant',
    separator: true,
    regex: tokens.descendant,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // default: descendant query
        var ancChQuery = newQuery();
        var descendant = newQuery();
        var ancestor = selector[selector.length - 1];
        ancChQuery.checks.push({
          type: Type.DESCENDANT,
          ancestor: ancestor,
          descendant: descendant
        });

        // the query in the selector should be the '>' itself
        replaceLastQuery(selector, query, ancChQuery);
        selector.compoundCount++;

        // we're now populating the descendant query with expressions that follow
        return descendant;
      } else if (selector.currentSubject === query) {
        // compound split query
        var compound = newQuery();
        var left = selector[selector.length - 1];
        var right = newQuery();
        var subject = newQuery();
        var _descendant = newQuery();
        var _ancestor = newQuery();

        // set up the root compound q
        compound.checks.push({
          type: Type.COMPOUND_SPLIT,
          left: left,
          right: right,
          subject: subject
        });

        // populate the subject and replace the q at the old spot (within left) with TRUE
        subject.checks = query.checks; // take the checks from the left
        query.checks = [{
          type: Type.TRUE
        }]; // checks under left refs the subject implicitly

        // set up the right q
        _ancestor.checks.push({
          type: Type.TRUE
        }); // ancestor implicitly refs the subject
        right.checks.push({
          type: Type.ANCESTOR,
          // type is swapped on right side queries
          ancestor: _ancestor,
          descendant: _descendant // empty for now
        });

        replaceLastQuery(selector, left, compound);

        // update the ref since we moved things around for `query`
        selector.currentSubject = subject;
        selector.compoundCount++;
        return _descendant; // now populating the right side's descendant
      } else {
        // ancestor query
        // info for parent query
        var _ancestor2 = newQuery();
        var _descendant2 = newQuery();
        var adQChecks = [{
          type: Type.ANCESTOR,
          ancestor: _ancestor2,
          descendant: _descendant2
        }];

        // the parent-child query takes the place of the query previously being populated
        _ancestor2.checks = query.checks; // the previous query contains the checks for the parent
        query.checks = adQChecks; // pc query takes over

        selector.compoundCount++;
        return _descendant2; // we're now populating the child
      }
    }
  }, {
    name: 'subject',
    modifier: true,
    regex: tokens.subject,
    populate: function populate(selector, query) {
      if (selector.currentSubject != null && selector.currentSubject !== query) {
        warn('Redefinition of subject in selector `' + selector.toString() + '`');
        return false;
      }
      selector.currentSubject = query;
      var topQ = selector[selector.length - 1];
      var topChk = topQ.checks[0];
      var topType = topChk == null ? null : topChk.type;
      if (topType === Type.DIRECTED_EDGE) {
        // directed edge with subject on the target

        // change to target node check
        topChk.type = Type.NODE_TARGET;
      } else if (topType === Type.UNDIRECTED_EDGE) {
        // undirected edge with subject on the second node

        // change to neighbor check
        topChk.type = Type.NODE_NEIGHBOR;
        topChk.node = topChk.nodes[1]; // second node is subject
        topChk.neighbor = topChk.nodes[0];

        // clean up unused fields for new type
        topChk.nodes = null;
      }
    }
  }];
  exprs.forEach(function (e) {
    return e.regexObj = new RegExp('^' + e.regex);
  });

  /**
   * Of all the expressions, find the first match in the remaining text.
   * @param {string} remaining The remaining text to parse
   * @returns The matched expression and the newly remaining text `{ expr, match, name, remaining }`
   */
  var consumeExpr = function consumeExpr(remaining) {
    var expr;
    var match;
    var name;
    for (var j = 0; j < exprs.length; j++) {
      var e = exprs[j];
      var n = e.name;
      var m = remaining.match(e.regexObj);
      if (m != null) {
        match = m;
        expr = e;
        name = n;
        var consumed = m[0];
        remaining = remaining.substring(consumed.length);
        break; // we've consumed one expr, so we can return now
      }
    }

    return {
      expr: expr,
      match: match,
      name: name,
      remaining: remaining
    };
  };

  /**
   * Consume all the leading whitespace
   * @param {string} remaining The text to consume
   * @returns The text with the leading whitespace removed
   */
  var consumeWhitespace = function consumeWhitespace(remaining) {
    var match = remaining.match(/^\s+/);
    if (match) {
      var consumed = match[0];
      remaining = remaining.substring(consumed.length);
    }
    return remaining;
  };

  /**
   * Parse the string and store the parsed representation in the Selector.
   * @param {string} selector The selector string
   * @returns `true` if the selector was successfully parsed, `false` otherwise
   */
  var parse = function parse(selector) {
    var self = this;
    var remaining = self.inputText = selector;
    var currentQuery = self[0] = newQuery();
    self.length = 1;
    remaining = consumeWhitespace(remaining); // get rid of leading whitespace

    for (;;) {
      var exprInfo = consumeExpr(remaining);
      if (exprInfo.expr == null) {
        warn('The selector `' + selector + '`is invalid');
        return false;
      } else {
        var args = exprInfo.match.slice(1);

        // let the token populate the selector object in currentQuery
        var ret = exprInfo.expr.populate(self, currentQuery, args);
        if (ret === false) {
          return false; // exit if population failed
        } else if (ret != null) {
          currentQuery = ret; // change the current query to be filled if the expr specifies
        }
      }

      remaining = exprInfo.remaining;

      // we're done when there's nothing left to parse
      if (remaining.match(/^\s*$/)) {
        break;
      }
    }
    var lastQ = self[self.length - 1];
    if (self.currentSubject != null) {
      lastQ.subject = self.currentSubject;
    }
    lastQ.edgeCount = self.edgeCount;
    lastQ.compoundCount = self.compoundCount;
    for (var i = 0; i < self.length; i++) {
      var q = self[i];

      // in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations
      if (q.compoundCount > 0 && q.edgeCount > 0) {
        warn('The selector `' + selector + '` is invalid because it uses both a compound selector and an edge selector');
        return false;
      }
      if (q.edgeCount > 1) {
        warn('The selector `' + selector + '` is invalid because it uses multiple edge selectors');
        return false;
      } else if (q.edgeCount === 1) {
        warn('The selector `' + selector + '` is deprecated.  Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons.  Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.');
      }
    }
    return true; // success
  };

  /**
   * Get the selector represented as a string.  This value uses default formatting,
   * so things like spacing may differ from the input text passed to the constructor.
   * @returns {string} The selector string
   */
  var toString = function toString() {
    if (this.toStringCache != null) {
      return this.toStringCache;
    }
    var clean = function clean(obj) {
      if (obj == null) {
        return '';
      } else {
        return obj;
      }
    };
    var cleanVal = function cleanVal(val) {
      if (string(val)) {
        return '"' + val + '"';
      } else {
        return clean(val);
      }
    };
    var space = function space(val) {
      return ' ' + val + ' ';
    };
    var checkToString = function checkToString(check, subject) {
      var type = check.type,
        value = check.value;
      switch (type) {
        case Type.GROUP:
          {
            var group = clean(value);
            return group.substring(0, group.length - 1);
          }
        case Type.DATA_COMPARE:
          {
            var field = check.field,
              operator = check.operator;
            return '[' + field + space(clean(operator)) + cleanVal(value) + ']';
          }
        case Type.DATA_BOOL:
          {
            var _operator = check.operator,
              _field = check.field;
            return '[' + clean(_operator) + _field + ']';
          }
        case Type.DATA_EXIST:
          {
            var _field2 = check.field;
            return '[' + _field2 + ']';
          }
        case Type.META_COMPARE:
          {
            var _operator2 = check.operator,
              _field3 = check.field;
            return '[[' + _field3 + space(clean(_operator2)) + cleanVal(value) + ']]';
          }
        case Type.STATE:
          {
            return value;
          }
        case Type.ID:
          {
            return '#' + value;
          }
        case Type.CLASS:
          {
            return '.' + value;
          }
        case Type.PARENT:
        case Type.CHILD:
          {
            return queryToString(check.parent, subject) + space('>') + queryToString(check.child, subject);
          }
        case Type.ANCESTOR:
        case Type.DESCENDANT:
          {
            return queryToString(check.ancestor, subject) + ' ' + queryToString(check.descendant, subject);
          }
        case Type.COMPOUND_SPLIT:
          {
            var lhs = queryToString(check.left, subject);
            var sub = queryToString(check.subject, subject);
            var rhs = queryToString(check.right, subject);
            return lhs + (lhs.length > 0 ? ' ' : '') + sub + rhs;
          }
        case Type.TRUE:
          {
            return '';
          }
      }
    };
    var queryToString = function queryToString(query, subject) {
      return query.checks.reduce(function (str, chk, i) {
        return str + (subject === query && i === 0 ? '$' : '') + checkToString(chk, subject);
      }, '');
    };
    var str = '';
    for (var i = 0; i < this.length; i++) {
      var query = this[i];
      str += queryToString(query, query.subject);
      if (this.length > 1 && i < this.length - 1) {
        str += ', ';
      }
    }
    this.toStringCache = str;
    return str;
  };
  var parse$1 = {
    parse: parse,
    toString: toString
  };

  var valCmp = function valCmp(fieldVal, operator, value) {
    var matches;
    var isFieldStr = string(fieldVal);
    var isFieldNum = number$1(fieldVal);
    var isValStr = string(value);
    var fieldStr, valStr;
    var caseInsensitive = false;
    var notExpr = false;
    var isIneqCmp = false;
    if (operator.indexOf('!') >= 0) {
      operator = operator.replace('!', '');
      notExpr = true;
    }
    if (operator.indexOf('@') >= 0) {
      operator = operator.replace('@', '');
      caseInsensitive = true;
    }
    if (isFieldStr || isValStr || caseInsensitive) {
      fieldStr = !isFieldStr && !isFieldNum ? '' : '' + fieldVal;
      valStr = '' + value;
    }

    // if we're doing a case insensitive comparison, then we're using a STRING comparison
    // even if we're comparing numbers
    if (caseInsensitive) {
      fieldVal = fieldStr = fieldStr.toLowerCase();
      value = valStr = valStr.toLowerCase();
    }
    switch (operator) {
      case '*=':
        matches = fieldStr.indexOf(valStr) >= 0;
        break;
      case '$=':
        matches = fieldStr.indexOf(valStr, fieldStr.length - valStr.length) >= 0;
        break;
      case '^=':
        matches = fieldStr.indexOf(valStr) === 0;
        break;
      case '=':
        matches = fieldVal === value;
        break;
      case '>':
        isIneqCmp = true;
        matches = fieldVal > value;
        break;
      case '>=':
        isIneqCmp = true;
        matches = fieldVal >= value;
        break;
      case '<':
        isIneqCmp = true;
        matches = fieldVal < value;
        break;
      case '<=':
        isIneqCmp = true;
        matches = fieldVal <= value;
        break;
      default:
        matches = false;
        break;
    }

    // apply the not op, but null vals for inequalities should always stay non-matching
    if (notExpr && (fieldVal != null || !isIneqCmp)) {
      matches = !matches;
    }
    return matches;
  };
  var boolCmp = function boolCmp(fieldVal, operator) {
    switch (operator) {
      case '?':
        return fieldVal ? true : false;
      case '!':
        return fieldVal ? false : true;
      case '^':
        return fieldVal === undefined;
    }
  };
  var existCmp = function existCmp(fieldVal) {
    return fieldVal !== undefined;
  };
  var data$1 = function data(ele, field) {
    return ele.data(field);
  };
  var meta = function meta(ele, field) {
    return ele[field]();
  };

  /** A lookup of `match(check, ele)` functions by `Type` int */
  var match = [];

  /**
   * Returns whether the query matches for the element
   * @param query The `{ type, value, ... }` query object
   * @param ele The element to compare against
  */
  var matches$1 = function matches(query, ele) {
    return query.checks.every(function (chk) {
      return match[chk.type](chk, ele);
    });
  };
  match[Type.GROUP] = function (check, ele) {
    var group = check.value;
    return group === '*' || group === ele.group();
  };
  match[Type.STATE] = function (check, ele) {
    var stateSelector = check.value;
    return stateSelectorMatches(stateSelector, ele);
  };
  match[Type.ID] = function (check, ele) {
    var id = check.value;
    return ele.id() === id;
  };
  match[Type.CLASS] = function (check, ele) {
    var cls = check.value;
    return ele.hasClass(cls);
  };
  match[Type.META_COMPARE] = function (check, ele) {
    var field = check.field,
      operator = check.operator,
      value = check.value;
    return valCmp(meta(ele, field), operator, value);
  };
  match[Type.DATA_COMPARE] = function (check, ele) {
    var field = check.field,
      operator = check.operator,
      value = check.value;
    return valCmp(data$1(ele, field), operator, value);
  };
  match[Type.DATA_BOOL] = function (check, ele) {
    var field = check.field,
      operator = check.operator;
    return boolCmp(data$1(ele, field), operator);
  };
  match[Type.DATA_EXIST] = function (check, ele) {
    var field = check.field;
      check.operator;
    return existCmp(data$1(ele, field));
  };
  match[Type.UNDIRECTED_EDGE] = function (check, ele) {
    var qA = check.nodes[0];
    var qB = check.nodes[1];
    var src = ele.source();
    var tgt = ele.target();
    return matches$1(qA, src) && matches$1(qB, tgt) || matches$1(qB, src) && matches$1(qA, tgt);
  };
  match[Type.NODE_NEIGHBOR] = function (check, ele) {
    return matches$1(check.node, ele) && ele.neighborhood().some(function (n) {
      return n.isNode() && matches$1(check.neighbor, n);
    });
  };
  match[Type.DIRECTED_EDGE] = function (check, ele) {
    return matches$1(check.source, ele.source()) && matches$1(check.target, ele.target());
  };
  match[Type.NODE_SOURCE] = function (check, ele) {
    return matches$1(check.source, ele) && ele.outgoers().some(function (n) {
      return n.isNode() && matches$1(check.target, n);
    });
  };
  match[Type.NODE_TARGET] = function (check, ele) {
    return matches$1(check.target, ele) && ele.incomers().some(function (n) {
      return n.isNode() && matches$1(check.source, n);
    });
  };
  match[Type.CHILD] = function (check, ele) {
    return matches$1(check.child, ele) && matches$1(check.parent, ele.parent());
  };
  match[Type.PARENT] = function (check, ele) {
    return matches$1(check.parent, ele) && ele.children().some(function (c) {
      return matches$1(check.child, c);
    });
  };
  match[Type.DESCENDANT] = function (check, ele) {
    return matches$1(check.descendant, ele) && ele.ancestors().some(function (a) {
      return matches$1(check.ancestor, a);
    });
  };
  match[Type.ANCESTOR] = function (check, ele) {
    return matches$1(check.ancestor, ele) && ele.descendants().some(function (d) {
      return matches$1(check.descendant, d);
    });
  };
  match[Type.COMPOUND_SPLIT] = function (check, ele) {
    return matches$1(check.subject, ele) && matches$1(check.left, ele) && matches$1(check.right, ele);
  };
  match[Type.TRUE] = function () {
    return true;
  };
  match[Type.COLLECTION] = function (check, ele) {
    var collection = check.value;
    return collection.has(ele);
  };
  match[Type.FILTER] = function (check, ele) {
    var filter = check.value;
    return filter(ele);
  };

  // filter an existing collection
  var filter = function filter(collection) {
    var self = this;

    // for 1 id #foo queries, just get the element
    if (self.length === 1 && self[0].checks.length === 1 && self[0].checks[0].type === Type.ID) {
      return collection.getElementById(self[0].checks[0].value).collection();
    }
    var selectorFunction = function selectorFunction(element) {
      for (var j = 0; j < self.length; j++) {
        var query = self[j];
        if (matches$1(query, element)) {
          return true;
        }
      }
      return false;
    };
    if (self.text() == null) {
      selectorFunction = function selectorFunction() {
        return true;
      };
    }
    return collection.filter(selectorFunction);
  }; // filter

  // does selector match a single element?
  var matches = function matches(ele) {
    var self = this;
    for (var j = 0; j < self.length; j++) {
      var query = self[j];
      if (matches$1(query, ele)) {
        return true;
      }
    }
    return false;
  }; // matches

  var matching = {
    matches: matches,
    filter: filter
  };

  var Selector = function Selector(selector) {
    this.inputText = selector;
    this.currentSubject = null;
    this.compoundCount = 0;
    this.edgeCount = 0;
    this.length = 0;
    if (selector == null || string(selector) && selector.match(/^\s*$/)) ; else if (elementOrCollection(selector)) {
      this.addQuery({
        checks: [{
          type: Type.COLLECTION,
          value: selector.collection()
        }]
      });
    } else if (fn$6(selector)) {
      this.addQuery({
        checks: [{
          type: Type.FILTER,
          value: selector
        }]
      });
    } else if (string(selector)) {
      if (!this.parse(selector)) {
        this.invalid = true;
      }
    } else {
      error('A selector must be created from a string; found ');
    }
  };
  var selfn = Selector.prototype;
  [parse$1, matching].forEach(function (p) {
    return extend(selfn, p);
  });
  selfn.text = function () {
    return this.inputText;
  };
  selfn.size = function () {
    return this.length;
  };
  selfn.eq = function (i) {
    return this[i];
  };
  selfn.sameText = function (otherSel) {
    return !this.invalid && !otherSel.invalid && this.text() === otherSel.text();
  };
  selfn.addQuery = function (q) {
    this[this.length++] = q;
  };
  selfn.selector = selfn.toString;

  var elesfn$g = {
    allAre: function allAre(selector) {
      var selObj = new Selector(selector);
      return this.every(function (ele) {
        return selObj.matches(ele);
      });
    },
    is: function is(selector) {
      var selObj = new Selector(selector);
      return this.some(function (ele) {
        return selObj.matches(ele);
      });
    },
    some: function some(fn, thisArg) {
      for (var i = 0; i < this.length; i++) {
        var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);
        if (ret) {
          return true;
        }
      }
      return false;
    },
    every: function every(fn, thisArg) {
      for (var i = 0; i < this.length; i++) {
        var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);
        if (!ret) {
          return false;
        }
      }
      return true;
    },
    same: function same(collection) {
      // cheap collection ref check
      if (this === collection) {
        return true;
      }
      collection = this.cy().collection(collection);
      var thisLength = this.length;
      var collectionLength = collection.length;

      // cheap length check
      if (thisLength !== collectionLength) {
        return false;
      }

      // cheap element ref check
      if (thisLength === 1) {
        return this[0] === collection[0];
      }
      return this.every(function (ele) {
        return collection.hasElementWithId(ele.id());
      });
    },
    anySame: function anySame(collection) {
      collection = this.cy().collection(collection);
      return this.some(function (ele) {
        return collection.hasElementWithId(ele.id());
      });
    },
    allAreNeighbors: function allAreNeighbors(collection) {
      collection = this.cy().collection(collection);
      var nhood = this.neighborhood();
      return collection.every(function (ele) {
        return nhood.hasElementWithId(ele.id());
      });
    },
    contains: function contains(collection) {
      collection = this.cy().collection(collection);
      var self = this;
      return collection.every(function (ele) {
        return self.hasElementWithId(ele.id());
      });
    }
  };
  elesfn$g.allAreNeighbours = elesfn$g.allAreNeighbors;
  elesfn$g.has = elesfn$g.contains;
  elesfn$g.equal = elesfn$g.equals = elesfn$g.same;

  var cache = function cache(fn, name) {
    return function traversalCache(arg1, arg2, arg3, arg4) {
      var selectorOrEles = arg1;
      var eles = this;
      var key;
      if (selectorOrEles == null) {
        key = '';
      } else if (elementOrCollection(selectorOrEles) && selectorOrEles.length === 1) {
        key = selectorOrEles.id();
      }
      if (eles.length === 1 && key) {
        var _p = eles[0]._private;
        var tch = _p.traversalCache = _p.traversalCache || {};
        var ch = tch[name] = tch[name] || [];
        var hash = hashString(key);
        var cacheHit = ch[hash];
        if (cacheHit) {
          return cacheHit;
        } else {
          return ch[hash] = fn.call(eles, arg1, arg2, arg3, arg4);
        }
      } else {
        return fn.call(eles, arg1, arg2, arg3, arg4);
      }
    };
  };

  var elesfn$f = {
    parent: function parent(selector) {
      var parents = [];

      // optimisation for single ele call
      if (this.length === 1) {
        var parent = this[0]._private.parent;
        if (parent) {
          return parent;
        }
      }
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var _parent = ele._private.parent;
        if (_parent) {
          parents.push(_parent);
        }
      }
      return this.spawn(parents, true).filter(selector);
    },
    parents: function parents(selector) {
      var parents = [];
      var eles = this.parent();
      while (eles.nonempty()) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          parents.push(ele);
        }
        eles = eles.parent();
      }
      return this.spawn(parents, true).filter(selector);
    },
    commonAncestors: function commonAncestors(selector) {
      var ancestors;
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var parents = ele.parents();
        ancestors = ancestors || parents;
        ancestors = ancestors.intersect(parents); // current list must be common with current ele parents set
      }

      return ancestors.filter(selector);
    },
    orphans: function orphans(selector) {
      return this.stdFilter(function (ele) {
        return ele.isOrphan();
      }).filter(selector);
    },
    nonorphans: function nonorphans(selector) {
      return this.stdFilter(function (ele) {
        return ele.isChild();
      }).filter(selector);
    },
    children: cache(function (selector) {
      var children = [];
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var eleChildren = ele._private.children;
        for (var j = 0; j < eleChildren.length; j++) {
          children.push(eleChildren[j]);
        }
      }
      return this.spawn(children, true).filter(selector);
    }, 'children'),
    siblings: function siblings(selector) {
      return this.parent().children().not(this).filter(selector);
    },
    isParent: function isParent() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.children.length !== 0;
      }
    },
    isChildless: function isChildless() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.children.length === 0;
      }
    },
    isChild: function isChild() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.parent != null;
      }
    },
    isOrphan: function isOrphan() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.parent == null;
      }
    },
    descendants: function descendants(selector) {
      var elements = [];
      function add(eles) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          elements.push(ele);
          if (ele.children().nonempty()) {
            add(ele.children());
          }
        }
      }
      add(this.children());
      return this.spawn(elements, true).filter(selector);
    }
  };
  function forEachCompound(eles, fn, includeSelf, recursiveStep) {
    var q = [];
    var did = new Set$1();
    var cy = eles.cy();
    var hasCompounds = cy.hasCompoundNodes();
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (includeSelf) {
        q.push(ele);
      } else if (hasCompounds) {
        recursiveStep(q, did, ele);
      }
    }
    while (q.length > 0) {
      var _ele = q.shift();
      fn(_ele);
      did.add(_ele.id());
      if (hasCompounds) {
        recursiveStep(q, did, _ele);
      }
    }
    return eles;
  }
  function addChildren(q, did, ele) {
    if (ele.isParent()) {
      var children = ele._private.children;
      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (!did.has(child.id())) {
          q.push(child);
        }
      }
    }
  }

  // very efficient version of eles.add( eles.descendants() ).forEach()
  // for internal use
  elesfn$f.forEachDown = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addChildren);
  };
  function addParent(q, did, ele) {
    if (ele.isChild()) {
      var parent = ele._private.parent;
      if (!did.has(parent.id())) {
        q.push(parent);
      }
    }
  }
  elesfn$f.forEachUp = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addParent);
  };
  function addParentAndChildren(q, did, ele) {
    addParent(q, did, ele);
    addChildren(q, did, ele);
  }
  elesfn$f.forEachUpAndDown = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addParentAndChildren);
  };

  // aliases
  elesfn$f.ancestors = elesfn$f.parents;

  var fn$5, elesfn$e;
  fn$5 = elesfn$e = {
    data: define.data({
      field: 'data',
      bindingEvent: 'data',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'data',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      immutableKeys: {
        'id': true,
        'source': true,
        'target': true,
        'parent': true
      },
      updateStyle: true
    }),
    removeData: define.removeData({
      field: 'data',
      event: 'data',
      triggerFnName: 'trigger',
      triggerEvent: true,
      immutableKeys: {
        'id': true,
        'source': true,
        'target': true,
        'parent': true
      },
      updateStyle: true
    }),
    scratch: define.data({
      field: 'scratch',
      bindingEvent: 'scratch',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'scratch',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeScratch: define.removeData({
      field: 'scratch',
      event: 'scratch',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    }),
    rscratch: define.data({
      field: 'rscratch',
      allowBinding: false,
      allowSetting: true,
      settingTriggersEvent: false,
      allowGetting: true
    }),
    removeRscratch: define.removeData({
      field: 'rscratch',
      triggerEvent: false
    }),
    id: function id() {
      var ele = this[0];
      if (ele) {
        return ele._private.data.id;
      }
    }
  };

  // aliases
  fn$5.attr = fn$5.data;
  fn$5.removeAttr = fn$5.removeData;
  var data = elesfn$e;

  var elesfn$d = {};
  function defineDegreeFunction(callback) {
    return function (includeLoops) {
      var self = this;
      if (includeLoops === undefined) {
        includeLoops = true;
      }
      if (self.length === 0) {
        return;
      }
      if (self.isNode() && !self.removed()) {
        var degree = 0;
        var node = self[0];
        var connectedEdges = node._private.edges;
        for (var i = 0; i < connectedEdges.length; i++) {
          var edge = connectedEdges[i];
          if (!includeLoops && edge.isLoop()) {
            continue;
          }
          degree += callback(node, edge);
        }
        return degree;
      } else {
        return;
      }
    };
  }
  extend(elesfn$d, {
    degree: defineDegreeFunction(function (node, edge) {
      if (edge.source().same(edge.target())) {
        return 2;
      } else {
        return 1;
      }
    }),
    indegree: defineDegreeFunction(function (node, edge) {
      if (edge.target().same(node)) {
        return 1;
      } else {
        return 0;
      }
    }),
    outdegree: defineDegreeFunction(function (node, edge) {
      if (edge.source().same(node)) {
        return 1;
      } else {
        return 0;
      }
    })
  });
  function defineDegreeBoundsFunction(degreeFn, callback) {
    return function (includeLoops) {
      var ret;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        var ele = nodes[i];
        var degree = ele[degreeFn](includeLoops);
        if (degree !== undefined && (ret === undefined || callback(degree, ret))) {
          ret = degree;
        }
      }
      return ret;
    };
  }
  extend(elesfn$d, {
    minDegree: defineDegreeBoundsFunction('degree', function (degree, min) {
      return degree < min;
    }),
    maxDegree: defineDegreeBoundsFunction('degree', function (degree, max) {
      return degree > max;
    }),
    minIndegree: defineDegreeBoundsFunction('indegree', function (degree, min) {
      return degree < min;
    }),
    maxIndegree: defineDegreeBoundsFunction('indegree', function (degree, max) {
      return degree > max;
    }),
    minOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, min) {
      return degree < min;
    }),
    maxOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, max) {
      return degree > max;
    })
  });
  extend(elesfn$d, {
    totalDegree: function totalDegree(includeLoops) {
      var total = 0;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        total += nodes[i].degree(includeLoops);
      }
      return total;
    }
  });

  var fn$4, elesfn$c;
  var beforePositionSet = function beforePositionSet(eles, newPos, silent) {
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (!ele.locked()) {
        var oldPos = ele._private.position;
        var delta = {
          x: newPos.x != null ? newPos.x - oldPos.x : 0,
          y: newPos.y != null ? newPos.y - oldPos.y : 0
        };
        if (ele.isParent() && !(delta.x === 0 && delta.y === 0)) {
          ele.children().shift(delta, silent);
        }
        ele.dirtyBoundingBoxCache();
      }
    }
  };
  var positionDef = {
    field: 'position',
    bindingEvent: 'position',
    allowBinding: true,
    allowSetting: true,
    settingEvent: 'position',
    settingTriggersEvent: true,
    triggerFnName: 'emitAndNotify',
    allowGetting: true,
    validKeys: ['x', 'y'],
    beforeGet: function beforeGet(ele) {
      ele.updateCompoundBounds();
    },
    beforeSet: function beforeSet(eles, newPos) {
      beforePositionSet(eles, newPos, false);
    },
    onSet: function onSet(eles) {
      eles.dirtyCompoundBoundsCache();
    },
    canSet: function canSet(ele) {
      return !ele.locked();
    }
  };
  fn$4 = elesfn$c = {
    position: define.data(positionDef),
    // position but no notification to renderer
    silentPosition: define.data(extend({}, positionDef, {
      allowBinding: false,
      allowSetting: true,
      settingTriggersEvent: false,
      allowGetting: false,
      beforeSet: function beforeSet(eles, newPos) {
        beforePositionSet(eles, newPos, true);
      },
      onSet: function onSet(eles) {
        eles.dirtyCompoundBoundsCache();
      }
    })),
    positions: function positions(pos, silent) {
      if (plainObject(pos)) {
        if (silent) {
          this.silentPosition(pos);
        } else {
          this.position(pos);
        }
      } else if (fn$6(pos)) {
        var _fn = pos;
        var cy = this.cy();
        cy.startBatch();
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];
          var _pos = void 0;
          if (_pos = _fn(ele, i)) {
            if (silent) {
              ele.silentPosition(_pos);
            } else {
              ele.position(_pos);
            }
          }
        }
        cy.endBatch();
      }
      return this; // chaining
    },

    silentPositions: function silentPositions(pos) {
      return this.positions(pos, true);
    },
    shift: function shift(dim, val, silent) {
      var delta;
      if (plainObject(dim)) {
        delta = {
          x: number$1(dim.x) ? dim.x : 0,
          y: number$1(dim.y) ? dim.y : 0
        };
        silent = val;
      } else if (string(dim) && number$1(val)) {
        delta = {
          x: 0,
          y: 0
        };
        delta[dim] = val;
      }
      if (delta != null) {
        var cy = this.cy();
        cy.startBatch();
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];

          // exclude any node that is a descendant of the calling collection
          if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) {
            continue;
          }
          var pos = ele.position();
          var newPos = {
            x: pos.x + delta.x,
            y: pos.y + delta.y
          };
          if (silent) {
            ele.silentPosition(newPos);
          } else {
            ele.position(newPos);
          }
        }
        cy.endBatch();
      }
      return this;
    },
    silentShift: function silentShift(dim, val) {
      if (plainObject(dim)) {
        this.shift(dim, true);
      } else if (string(dim) && number$1(val)) {
        this.shift(dim, val, true);
      }
      return this;
    },
    // get/set the rendered (i.e. on screen) positon of the element
    renderedPosition: function renderedPosition(dim, val) {
      var ele = this[0];
      var cy = this.cy();
      var zoom = cy.zoom();
      var pan = cy.pan();
      var rpos = plainObject(dim) ? dim : undefined;
      var setting = rpos !== undefined || val !== undefined && string(dim);
      if (ele && ele.isNode()) {
        // must have an element and must be a node to return position
        if (setting) {
          for (var i = 0; i < this.length; i++) {
            var _ele = this[i];
            if (val !== undefined) {
              // set one dimension
              _ele.position(dim, (val - pan[dim]) / zoom);
            } else if (rpos !== undefined) {
              // set whole position
              _ele.position(renderedToModelPosition(rpos, zoom, pan));
            }
          }
        } else {
          // getting
          var pos = ele.position();
          rpos = modelToRenderedPosition(pos, zoom, pan);
          if (dim === undefined) {
            // then return the whole rendered position
            return rpos;
          } else {
            // then return the specified dimension
            return rpos[dim];
          }
        }
      } else if (!setting) {
        return undefined; // for empty collection case
      }

      return this; // chaining
    },

    // get/set the position relative to the parent
    relativePosition: function relativePosition(dim, val) {
      var ele = this[0];
      var cy = this.cy();
      var ppos = plainObject(dim) ? dim : undefined;
      var setting = ppos !== undefined || val !== undefined && string(dim);
      var hasCompoundNodes = cy.hasCompoundNodes();
      if (ele && ele.isNode()) {
        // must have an element and must be a node to return position
        if (setting) {
          for (var i = 0; i < this.length; i++) {
            var _ele2 = this[i];
            var parent = hasCompoundNodes ? _ele2.parent() : null;
            var hasParent = parent && parent.length > 0;
            var relativeToParent = hasParent;
            if (hasParent) {
              parent = parent[0];
            }
            var origin = relativeToParent ? parent.position() : {
              x: 0,
              y: 0
            };
            if (val !== undefined) {
              // set one dimension
              _ele2.position(dim, val + origin[dim]);
            } else if (ppos !== undefined) {
              // set whole position
              _ele2.position({
                x: ppos.x + origin.x,
                y: ppos.y + origin.y
              });
            }
          }
        } else {
          // getting
          var pos = ele.position();
          var _parent = hasCompoundNodes ? ele.parent() : null;
          var _hasParent = _parent && _parent.length > 0;
          var _relativeToParent = _hasParent;
          if (_hasParent) {
            _parent = _parent[0];
          }
          var _origin = _relativeToParent ? _parent.position() : {
            x: 0,
            y: 0
          };
          ppos = {
            x: pos.x - _origin.x,
            y: pos.y - _origin.y
          };
          if (dim === undefined) {
            // then return the whole rendered position
            return ppos;
          } else {
            // then return the specified dimension
            return ppos[dim];
          }
        }
      } else if (!setting) {
        return undefined; // for empty collection case
      }

      return this; // chaining
    }
  };

  // aliases
  fn$4.modelPosition = fn$4.point = fn$4.position;
  fn$4.modelPositions = fn$4.points = fn$4.positions;
  fn$4.renderedPoint = fn$4.renderedPosition;
  fn$4.relativePoint = fn$4.relativePosition;
  var position = elesfn$c;

  var fn$3, elesfn$b;
  fn$3 = elesfn$b = {};
  elesfn$b.renderedBoundingBox = function (options) {
    var bb = this.boundingBox(options);
    var cy = this.cy();
    var zoom = cy.zoom();
    var pan = cy.pan();
    var x1 = bb.x1 * zoom + pan.x;
    var x2 = bb.x2 * zoom + pan.x;
    var y1 = bb.y1 * zoom + pan.y;
    var y2 = bb.y2 * zoom + pan.y;
    return {
      x1: x1,
      x2: x2,
      y1: y1,
      y2: y2,
      w: x2 - x1,
      h: y2 - y1
    };
  };
  elesfn$b.dirtyCompoundBoundsCache = function () {
    var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var cy = this.cy();
    if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {
      return this;
    }
    this.forEachUp(function (ele) {
      if (ele.isParent()) {
        var _p = ele._private;
        _p.compoundBoundsClean = false;
        _p.bbCache = null;
        if (!silent) {
          ele.emitAndNotify('bounds');
        }
      }
    });
    return this;
  };
  elesfn$b.updateCompoundBounds = function () {
    var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var cy = this.cy();

    // not possible to do on non-compound graphs or with the style disabled
    if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {
      return this;
    }

    // save cycles when batching -- but bounds will be stale (or not exist yet)
    if (!force && cy.batching()) {
      return this;
    }
    function update(parent) {
      if (!parent.isParent()) {
        return;
      }
      var _p = parent._private;
      var children = parent.children();
      var includeLabels = parent.pstyle('compound-sizing-wrt-labels').value === 'include';
      var min = {
        width: {
          val: parent.pstyle('min-width').pfValue,
          left: parent.pstyle('min-width-bias-left'),
          right: parent.pstyle('min-width-bias-right')
        },
        height: {
          val: parent.pstyle('min-height').pfValue,
          top: parent.pstyle('min-height-bias-top'),
          bottom: parent.pstyle('min-height-bias-bottom')
        }
      };
      var bb = children.boundingBox({
        includeLabels: includeLabels,
        includeOverlays: false,
        // updating the compound bounds happens outside of the regular
        // cache cycle (i.e. before fired events)
        useCache: false
      });
      var pos = _p.position;

      // if children take up zero area then keep position and fall back on stylesheet w/h
      if (bb.w === 0 || bb.h === 0) {
        bb = {
          w: parent.pstyle('width').pfValue,
          h: parent.pstyle('height').pfValue
        };
        bb.x1 = pos.x - bb.w / 2;
        bb.x2 = pos.x + bb.w / 2;
        bb.y1 = pos.y - bb.h / 2;
        bb.y2 = pos.y + bb.h / 2;
      }
      function computeBiasValues(propDiff, propBias, propBiasComplement) {
        var biasDiff = 0;
        var biasComplementDiff = 0;
        var biasTotal = propBias + propBiasComplement;
        if (propDiff > 0 && biasTotal > 0) {
          biasDiff = propBias / biasTotal * propDiff;
          biasComplementDiff = propBiasComplement / biasTotal * propDiff;
        }
        return {
          biasDiff: biasDiff,
          biasComplementDiff: biasComplementDiff
        };
      }
      function computePaddingValues(width, height, paddingObject, relativeTo) {
        // Assuming percentage is number from 0 to 1
        if (paddingObject.units === '%') {
          switch (relativeTo) {
            case 'width':
              return width > 0 ? paddingObject.pfValue * width : 0;
            case 'height':
              return height > 0 ? paddingObject.pfValue * height : 0;
            case 'average':
              return width > 0 && height > 0 ? paddingObject.pfValue * (width + height) / 2 : 0;
            case 'min':
              return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * height : paddingObject.pfValue * width : 0;
            case 'max':
              return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * width : paddingObject.pfValue * height : 0;
            default:
              return 0;
          }
        } else if (paddingObject.units === 'px') {
          return paddingObject.pfValue;
        } else {
          return 0;
        }
      }
      var leftVal = min.width.left.value;
      if (min.width.left.units === 'px' && min.width.val > 0) {
        leftVal = leftVal * 100 / min.width.val;
      }
      var rightVal = min.width.right.value;
      if (min.width.right.units === 'px' && min.width.val > 0) {
        rightVal = rightVal * 100 / min.width.val;
      }
      var topVal = min.height.top.value;
      if (min.height.top.units === 'px' && min.height.val > 0) {
        topVal = topVal * 100 / min.height.val;
      }
      var bottomVal = min.height.bottom.value;
      if (min.height.bottom.units === 'px' && min.height.val > 0) {
        bottomVal = bottomVal * 100 / min.height.val;
      }
      var widthBiasDiffs = computeBiasValues(min.width.val - bb.w, leftVal, rightVal);
      var diffLeft = widthBiasDiffs.biasDiff;
      var diffRight = widthBiasDiffs.biasComplementDiff;
      var heightBiasDiffs = computeBiasValues(min.height.val - bb.h, topVal, bottomVal);
      var diffTop = heightBiasDiffs.biasDiff;
      var diffBottom = heightBiasDiffs.biasComplementDiff;
      _p.autoPadding = computePaddingValues(bb.w, bb.h, parent.pstyle('padding'), parent.pstyle('padding-relative-to').value);
      _p.autoWidth = Math.max(bb.w, min.width.val);
      pos.x = (-diffLeft + bb.x1 + bb.x2 + diffRight) / 2;
      _p.autoHeight = Math.max(bb.h, min.height.val);
      pos.y = (-diffTop + bb.y1 + bb.y2 + diffBottom) / 2;
    }
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var _p = ele._private;
      if (!_p.compoundBoundsClean || force) {
        update(ele);
        if (!cy.batching()) {
          _p.compoundBoundsClean = true;
        }
      }
    }
    return this;
  };
  var noninf = function noninf(x) {
    if (x === Infinity || x === -Infinity) {
      return 0;
    }
    return x;
  };
  var updateBounds = function updateBounds(b, x1, y1, x2, y2) {
    // don't update with zero area boxes
    if (x2 - x1 === 0 || y2 - y1 === 0) {
      return;
    }

    // don't update with null dim
    if (x1 == null || y1 == null || x2 == null || y2 == null) {
      return;
    }
    b.x1 = x1 < b.x1 ? x1 : b.x1;
    b.x2 = x2 > b.x2 ? x2 : b.x2;
    b.y1 = y1 < b.y1 ? y1 : b.y1;
    b.y2 = y2 > b.y2 ? y2 : b.y2;
    b.w = b.x2 - b.x1;
    b.h = b.y2 - b.y1;
  };
  var updateBoundsFromBox = function updateBoundsFromBox(b, b2) {
    if (b2 == null) {
      return b;
    }
    return updateBounds(b, b2.x1, b2.y1, b2.x2, b2.y2);
  };
  var prefixedProperty = function prefixedProperty(obj, field, prefix) {
    return getPrefixedProperty(obj, field, prefix);
  };
  var updateBoundsFromArrow = function updateBoundsFromArrow(bounds, ele, prefix) {
    if (ele.cy().headless()) {
      return;
    }
    var _p = ele._private;
    var rstyle = _p.rstyle;
    var halfArW = rstyle.arrowWidth / 2;
    var arrowType = ele.pstyle(prefix + '-arrow-shape').value;
    var x;
    var y;
    if (arrowType !== 'none') {
      if (prefix === 'source') {
        x = rstyle.srcX;
        y = rstyle.srcY;
      } else if (prefix === 'target') {
        x = rstyle.tgtX;
        y = rstyle.tgtY;
      } else {
        x = rstyle.midX;
        y = rstyle.midY;
      }

      // always store the individual arrow bounds
      var bbs = _p.arrowBounds = _p.arrowBounds || {};
      var bb = bbs[prefix] = bbs[prefix] || {};
      bb.x1 = x - halfArW;
      bb.y1 = y - halfArW;
      bb.x2 = x + halfArW;
      bb.y2 = y + halfArW;
      bb.w = bb.x2 - bb.x1;
      bb.h = bb.y2 - bb.y1;
      expandBoundingBox(bb, 1);
      updateBounds(bounds, bb.x1, bb.y1, bb.x2, bb.y2);
    }
  };
  var updateBoundsFromLabel = function updateBoundsFromLabel(bounds, ele, prefix) {
    if (ele.cy().headless()) {
      return;
    }
    var prefixDash;
    if (prefix) {
      prefixDash = prefix + '-';
    } else {
      prefixDash = '';
    }
    var _p = ele._private;
    var rstyle = _p.rstyle;
    var label = ele.pstyle(prefixDash + 'label').strValue;
    if (label) {
      var halign = ele.pstyle('text-halign');
      var valign = ele.pstyle('text-valign');
      var labelWidth = prefixedProperty(rstyle, 'labelWidth', prefix);
      var labelHeight = prefixedProperty(rstyle, 'labelHeight', prefix);
      var labelX = prefixedProperty(rstyle, 'labelX', prefix);
      var labelY = prefixedProperty(rstyle, 'labelY', prefix);
      var marginX = ele.pstyle(prefixDash + 'text-margin-x').pfValue;
      var marginY = ele.pstyle(prefixDash + 'text-margin-y').pfValue;
      var isEdge = ele.isEdge();
      var rotation = ele.pstyle(prefixDash + 'text-rotation');
      var outlineWidth = ele.pstyle('text-outline-width').pfValue;
      var borderWidth = ele.pstyle('text-border-width').pfValue;
      var halfBorderWidth = borderWidth / 2;
      var padding = ele.pstyle('text-background-padding').pfValue;
      var marginOfError = 2; // expand to work around browser dimension inaccuracies

      var lh = labelHeight;
      var lw = labelWidth;
      var lw_2 = lw / 2;
      var lh_2 = lh / 2;
      var lx1, lx2, ly1, ly2;
      if (isEdge) {
        lx1 = labelX - lw_2;
        lx2 = labelX + lw_2;
        ly1 = labelY - lh_2;
        ly2 = labelY + lh_2;
      } else {
        switch (halign.value) {
          case 'left':
            lx1 = labelX - lw;
            lx2 = labelX;
            break;
          case 'center':
            lx1 = labelX - lw_2;
            lx2 = labelX + lw_2;
            break;
          case 'right':
            lx1 = labelX;
            lx2 = labelX + lw;
            break;
        }
        switch (valign.value) {
          case 'top':
            ly1 = labelY - lh;
            ly2 = labelY;
            break;
          case 'center':
            ly1 = labelY - lh_2;
            ly2 = labelY + lh_2;
            break;
          case 'bottom':
            ly1 = labelY;
            ly2 = labelY + lh;
            break;
        }
      }

      // shift by margin and expand by outline and border
      lx1 += marginX - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;
      lx2 += marginX + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;
      ly1 += marginY - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;
      ly2 += marginY + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;

      // always store the unrotated label bounds separately
      var bbPrefix = prefix || 'main';
      var bbs = _p.labelBounds;
      var bb = bbs[bbPrefix] = bbs[bbPrefix] || {};
      bb.x1 = lx1;
      bb.y1 = ly1;
      bb.x2 = lx2;
      bb.y2 = ly2;
      bb.w = lx2 - lx1;
      bb.h = ly2 - ly1;
      var isAutorotate = isEdge && rotation.strValue === 'autorotate';
      var isPfValue = rotation.pfValue != null && rotation.pfValue !== 0;
      if (isAutorotate || isPfValue) {
        var theta = isAutorotate ? prefixedProperty(_p.rstyle, 'labelAngle', prefix) : rotation.pfValue;
        var cos = Math.cos(theta);
        var sin = Math.sin(theta);

        // rotation point (default value for center-center)
        var xo = (lx1 + lx2) / 2;
        var yo = (ly1 + ly2) / 2;
        if (!isEdge) {
          switch (halign.value) {
            case 'left':
              xo = lx2;
              break;
            case 'right':
              xo = lx1;
              break;
          }
          switch (valign.value) {
            case 'top':
              yo = ly2;
              break;
            case 'bottom':
              yo = ly1;
              break;
          }
        }
        var rotate = function rotate(x, y) {
          x = x - xo;
          y = y - yo;
          return {
            x: x * cos - y * sin + xo,
            y: x * sin + y * cos + yo
          };
        };
        var px1y1 = rotate(lx1, ly1);
        var px1y2 = rotate(lx1, ly2);
        var px2y1 = rotate(lx2, ly1);
        var px2y2 = rotate(lx2, ly2);
        lx1 = Math.min(px1y1.x, px1y2.x, px2y1.x, px2y2.x);
        lx2 = Math.max(px1y1.x, px1y2.x, px2y1.x, px2y2.x);
        ly1 = Math.min(px1y1.y, px1y2.y, px2y1.y, px2y2.y);
        ly2 = Math.max(px1y1.y, px1y2.y, px2y1.y, px2y2.y);
      }
      var bbPrefixRot = bbPrefix + 'Rot';
      var bbRot = bbs[bbPrefixRot] = bbs[bbPrefixRot] || {};
      bbRot.x1 = lx1;
      bbRot.y1 = ly1;
      bbRot.x2 = lx2;
      bbRot.y2 = ly2;
      bbRot.w = lx2 - lx1;
      bbRot.h = ly2 - ly1;
      updateBounds(bounds, lx1, ly1, lx2, ly2);
      updateBounds(_p.labelBounds.all, lx1, ly1, lx2, ly2);
    }
    return bounds;
  };
  var updateBoundsFromOutline = function updateBoundsFromOutline(bounds, ele) {
    if (ele.cy().headless()) {
      return;
    }
    var outlineOpacity = ele.pstyle('outline-opacity').value;
    var outlineWidth = ele.pstyle('outline-width').value;
    if (outlineOpacity > 0 && outlineWidth > 0) {
      var outlineOffset = ele.pstyle('outline-offset').value;
      var nodeShape = ele.pstyle('shape').value;
      var outlineSize = outlineWidth + outlineOffset;
      var scaleX = (bounds.w + outlineSize * 2) / bounds.w;
      var scaleY = (bounds.h + outlineSize * 2) / bounds.h;
      var xOffset = 0;
      var yOffset = 0;
      if (["diamond", "pentagon", "round-triangle"].includes(nodeShape)) {
        scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;
        yOffset = -outlineSize / 3.6;
      } else if (["concave-hexagon", "rhomboid", "right-rhomboid"].includes(nodeShape)) {
        scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;
      } else if (nodeShape === "star") {
        scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;
        scaleY = (bounds.h + outlineSize * 2.6) / bounds.h;
        yOffset = -outlineSize / 3.8;
      } else if (nodeShape === "triangle") {
        scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;
        scaleY = (bounds.h + outlineSize * 2.4) / bounds.h;
        yOffset = -outlineSize / 1.4;
      } else if (nodeShape === "vee") {
        scaleX = (bounds.w + outlineSize * 4.4) / bounds.w;
        scaleY = (bounds.h + outlineSize * 3.8) / bounds.h;
        yOffset = -outlineSize * .5;
      }
      var hDelta = bounds.h * scaleY - bounds.h;
      var wDelta = bounds.w * scaleX - bounds.w;
      expandBoundingBoxSides(bounds, [Math.ceil(hDelta / 2), Math.ceil(wDelta / 2)]);
      if (xOffset != 0 || yOffset !== 0) {
        var oBounds = shiftBoundingBox(bounds, xOffset, yOffset);
        updateBoundingBox(bounds, oBounds);
      }
    }
  };

  // get the bounding box of the elements (in raw model position)
  var boundingBoxImpl = function boundingBoxImpl(ele, options) {
    var cy = ele._private.cy;
    var styleEnabled = cy.styleEnabled();
    var headless = cy.headless();
    var bounds = makeBoundingBox();
    var _p = ele._private;
    var isNode = ele.isNode();
    var isEdge = ele.isEdge();
    var ex1, ex2, ey1, ey2; // extrema of body / lines
    var x, y; // node pos
    var rstyle = _p.rstyle;
    var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : [0];

    // must use `display` prop only, as reading `compound.width()` causes recursion
    // (other factors like width values will be considered later in this function anyway)
    var isDisplayed = function isDisplayed(ele) {
      return ele.pstyle('display').value !== 'none';
    };
    var displayed = !styleEnabled || isDisplayed(ele)

    // must take into account connected nodes b/c of implicit edge hiding on display:none node
    && (!isEdge || isDisplayed(ele.source()) && isDisplayed(ele.target()));
    if (displayed) {
      // displayed suffices, since we will find zero area eles anyway
      var overlayOpacity = 0;
      var overlayPadding = 0;
      if (styleEnabled && options.includeOverlays) {
        overlayOpacity = ele.pstyle('overlay-opacity').value;
        if (overlayOpacity !== 0) {
          overlayPadding = ele.pstyle('overlay-padding').value;
        }
      }
      var underlayOpacity = 0;
      var underlayPadding = 0;
      if (styleEnabled && options.includeUnderlays) {
        underlayOpacity = ele.pstyle('underlay-opacity').value;
        if (underlayOpacity !== 0) {
          underlayPadding = ele.pstyle('underlay-padding').value;
        }
      }
      var padding = Math.max(overlayPadding, underlayPadding);
      var w = 0;
      var wHalf = 0;
      if (styleEnabled) {
        w = ele.pstyle('width').pfValue;
        wHalf = w / 2;
      }
      if (isNode && options.includeNodes) {
        var pos = ele.position();
        x = pos.x;
        y = pos.y;
        var _w = ele.outerWidth();
        var halfW = _w / 2;
        var h = ele.outerHeight();
        var halfH = h / 2;

        // handle node dimensions
        /////////////////////////

        ex1 = x - halfW;
        ex2 = x + halfW;
        ey1 = y - halfH;
        ey2 = y + halfH;
        updateBounds(bounds, ex1, ey1, ex2, ey2);
        if (styleEnabled && options.includeOutlines) {
          updateBoundsFromOutline(bounds, ele);
        }
      } else if (isEdge && options.includeEdges) {
        if (styleEnabled && !headless) {
          var curveStyle = ele.pstyle('curve-style').strValue;

          // handle edge dimensions (rough box estimate)
          //////////////////////////////////////////////

          ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX);
          ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX);
          ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY);
          ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY);

          // take into account edge width
          ex1 -= wHalf;
          ex2 += wHalf;
          ey1 -= wHalf;
          ey2 += wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);

          // precise edges
          ////////////////

          if (curveStyle === 'haystack') {
            var hpts = rstyle.haystackPts;
            if (hpts && hpts.length === 2) {
              ex1 = hpts[0].x;
              ey1 = hpts[0].y;
              ex2 = hpts[1].x;
              ey2 = hpts[1].y;
              if (ex1 > ex2) {
                var temp = ex1;
                ex1 = ex2;
                ex2 = temp;
              }
              if (ey1 > ey2) {
                var _temp = ey1;
                ey1 = ey2;
                ey2 = _temp;
              }
              updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf);
            }
          } else if (curveStyle === 'bezier' || curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'taxi') {
            var pts;
            switch (curveStyle) {
              case 'bezier':
              case 'unbundled-bezier':
                pts = rstyle.bezierPts;
                break;
              case 'segments':
              case 'taxi':
                pts = rstyle.linePts;
                break;
            }
            if (pts != null) {
              for (var j = 0; j < pts.length; j++) {
                var pt = pts[j];
                ex1 = pt.x - wHalf;
                ex2 = pt.x + wHalf;
                ey1 = pt.y - wHalf;
                ey2 = pt.y + wHalf;
                updateBounds(bounds, ex1, ey1, ex2, ey2);
              }
            }
          } // bezier-like or segment-like edge
        } else {
          // headless or style disabled

          // fallback on source and target positions
          //////////////////////////////////////////

          var n1 = ele.source();
          var n1pos = n1.position();
          var n2 = ele.target();
          var n2pos = n2.position();
          ex1 = n1pos.x;
          ex2 = n2pos.x;
          ey1 = n1pos.y;
          ey2 = n2pos.y;
          if (ex1 > ex2) {
            var _temp2 = ex1;
            ex1 = ex2;
            ex2 = _temp2;
          }
          if (ey1 > ey2) {
            var _temp3 = ey1;
            ey1 = ey2;
            ey2 = _temp3;
          }

          // take into account edge width
          ex1 -= wHalf;
          ex2 += wHalf;
          ey1 -= wHalf;
          ey2 += wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);
        } // headless or style disabled
      } // edges

      // handle edge arrow size
      /////////////////////////

      if (styleEnabled && options.includeEdges && isEdge) {
        updateBoundsFromArrow(bounds, ele, 'mid-source');
        updateBoundsFromArrow(bounds, ele, 'mid-target');
        updateBoundsFromArrow(bounds, ele, 'source');
        updateBoundsFromArrow(bounds, ele, 'target');
      }

      // ghost
      ////////

      if (styleEnabled) {
        var ghost = ele.pstyle('ghost').value === 'yes';
        if (ghost) {
          var gx = ele.pstyle('ghost-offset-x').pfValue;
          var gy = ele.pstyle('ghost-offset-y').pfValue;
          updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy);
        }
      }

      // always store the body bounds separately from the labels
      var bbBody = _p.bodyBounds = _p.bodyBounds || {};
      assignBoundingBox(bbBody, bounds);
      expandBoundingBoxSides(bbBody, manualExpansion);
      expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies

      // overlay
      //////////

      if (styleEnabled) {
        ex1 = bounds.x1;
        ex2 = bounds.x2;
        ey1 = bounds.y1;
        ey2 = bounds.y2;
        updateBounds(bounds, ex1 - padding, ey1 - padding, ex2 + padding, ey2 + padding);
      }

      // always store the body bounds separately from the labels
      var bbOverlay = _p.overlayBounds = _p.overlayBounds || {};
      assignBoundingBox(bbOverlay, bounds);
      expandBoundingBoxSides(bbOverlay, manualExpansion);
      expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies

      // handle label dimensions
      //////////////////////////

      var bbLabels = _p.labelBounds = _p.labelBounds || {};
      if (bbLabels.all != null) {
        clearBoundingBox(bbLabels.all);
      } else {
        bbLabels.all = makeBoundingBox();
      }
      if (styleEnabled && options.includeLabels) {
        if (options.includeMainLabels) {
          updateBoundsFromLabel(bounds, ele, null);
        }
        if (isEdge) {
          if (options.includeSourceLabels) {
            updateBoundsFromLabel(bounds, ele, 'source');
          }
          if (options.includeTargetLabels) {
            updateBoundsFromLabel(bounds, ele, 'target');
          }
        }
      } // style enabled for labels
    } // if displayed

    bounds.x1 = noninf(bounds.x1);
    bounds.y1 = noninf(bounds.y1);
    bounds.x2 = noninf(bounds.x2);
    bounds.y2 = noninf(bounds.y2);
    bounds.w = noninf(bounds.x2 - bounds.x1);
    bounds.h = noninf(bounds.y2 - bounds.y1);
    if (bounds.w > 0 && bounds.h > 0 && displayed) {
      expandBoundingBoxSides(bounds, manualExpansion);

      // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides
      expandBoundingBox(bounds, 1);
    }
    return bounds;
  };
  var getKey = function getKey(opts) {
    var i = 0;
    var tf = function tf(val) {
      return (val ? 1 : 0) << i++;
    };
    var key = 0;
    key += tf(opts.incudeNodes);
    key += tf(opts.includeEdges);
    key += tf(opts.includeLabels);
    key += tf(opts.includeMainLabels);
    key += tf(opts.includeSourceLabels);
    key += tf(opts.includeTargetLabels);
    key += tf(opts.includeOverlays);
    key += tf(opts.includeOutlines);
    return key;
  };
  var getBoundingBoxPosKey = function getBoundingBoxPosKey(ele) {
    if (ele.isEdge()) {
      var p1 = ele.source().position();
      var p2 = ele.target().position();
      var r = function r(x) {
        return Math.round(x);
      };
      return hashIntsArray([r(p1.x), r(p1.y), r(p2.x), r(p2.y)]);
    } else {
      return 0;
    }
  };
  var cachedBoundingBoxImpl = function cachedBoundingBoxImpl(ele, opts) {
    var _p = ele._private;
    var bb;
    var isEdge = ele.isEdge();
    var key = opts == null ? defBbOptsKey : getKey(opts);
    var usingDefOpts = key === defBbOptsKey;
    var currPosKey = getBoundingBoxPosKey(ele);
    var isPosKeySame = _p.bbCachePosKey === currPosKey;
    var useCache = opts.useCache && isPosKeySame;
    var isDirty = function isDirty(ele) {
      return ele._private.bbCache == null || ele._private.styleDirty;
    };
    var needRecalc = !useCache || isDirty(ele) || isEdge && isDirty(ele.source()) || isDirty(ele.target());
    if (needRecalc) {
      if (!isPosKeySame) {
        ele.recalculateRenderedStyle(useCache);
      }
      bb = boundingBoxImpl(ele, defBbOpts);
      _p.bbCache = bb;
      _p.bbCachePosKey = currPosKey;
    } else {
      bb = _p.bbCache;
    }

    // not using def opts => need to build up bb from combination of sub bbs
    if (!usingDefOpts) {
      var isNode = ele.isNode();
      bb = makeBoundingBox();
      if (opts.includeNodes && isNode || opts.includeEdges && !isNode) {
        if (opts.includeOverlays) {
          updateBoundsFromBox(bb, _p.overlayBounds);
        } else {
          updateBoundsFromBox(bb, _p.bodyBounds);
        }
      }
      if (opts.includeLabels) {
        if (opts.includeMainLabels && (!isEdge || opts.includeSourceLabels && opts.includeTargetLabels)) {
          updateBoundsFromBox(bb, _p.labelBounds.all);
        } else {
          if (opts.includeMainLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.mainRot);
          }
          if (opts.includeSourceLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.sourceRot);
          }
          if (opts.includeTargetLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.targetRot);
          }
        }
      }
      bb.w = bb.x2 - bb.x1;
      bb.h = bb.y2 - bb.y1;
    }
    return bb;
  };
  var defBbOpts = {
    includeNodes: true,
    includeEdges: true,
    includeLabels: true,
    includeMainLabels: true,
    includeSourceLabels: true,
    includeTargetLabels: true,
    includeOverlays: true,
    includeUnderlays: true,
    includeOutlines: true,
    useCache: true
  };
  var defBbOptsKey = getKey(defBbOpts);
  var filledBbOpts = defaults$g(defBbOpts);
  elesfn$b.boundingBox = function (options) {
    var bounds;

    // the main usecase is ele.boundingBox() for a single element with no/def options
    // specified s.t. the cache is used, so check for this case to make it faster by
    // avoiding the overhead of the rest of the function
    if (this.length === 1 && this[0]._private.bbCache != null && !this[0]._private.styleDirty && (options === undefined || options.useCache === undefined || options.useCache === true)) {
      if (options === undefined) {
        options = defBbOpts;
      } else {
        options = filledBbOpts(options);
      }
      bounds = cachedBoundingBoxImpl(this[0], options);
    } else {
      bounds = makeBoundingBox();
      options = options || defBbOpts;
      var opts = filledBbOpts(options);
      var eles = this;
      var cy = eles.cy();
      var styleEnabled = cy.styleEnabled();
      if (styleEnabled) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var _p = ele._private;
          var currPosKey = getBoundingBoxPosKey(ele);
          var isPosKeySame = _p.bbCachePosKey === currPosKey;
          var useCache = opts.useCache && isPosKeySame && !_p.styleDirty;
          ele.recalculateRenderedStyle(useCache);
        }
      }
      this.updateCompoundBounds(!options.useCache);
      for (var _i = 0; _i < eles.length; _i++) {
        var _ele = eles[_i];
        updateBoundsFromBox(bounds, cachedBoundingBoxImpl(_ele, opts));
      }
    }
    bounds.x1 = noninf(bounds.x1);
    bounds.y1 = noninf(bounds.y1);
    bounds.x2 = noninf(bounds.x2);
    bounds.y2 = noninf(bounds.y2);
    bounds.w = noninf(bounds.x2 - bounds.x1);
    bounds.h = noninf(bounds.y2 - bounds.y1);
    return bounds;
  };
  elesfn$b.dirtyBoundingBoxCache = function () {
    for (var i = 0; i < this.length; i++) {
      var _p = this[i]._private;
      _p.bbCache = null;
      _p.bbCachePosKey = null;
      _p.bodyBounds = null;
      _p.overlayBounds = null;
      _p.labelBounds.all = null;
      _p.labelBounds.source = null;
      _p.labelBounds.target = null;
      _p.labelBounds.main = null;
      _p.labelBounds.sourceRot = null;
      _p.labelBounds.targetRot = null;
      _p.labelBounds.mainRot = null;
      _p.arrowBounds.source = null;
      _p.arrowBounds.target = null;
      _p.arrowBounds['mid-source'] = null;
      _p.arrowBounds['mid-target'] = null;
    }
    this.emitAndNotify('bounds');
    return this;
  };

  // private helper to get bounding box for custom node positions
  // - good for perf in certain cases but currently requires dirtying the rendered style
  // - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer...
  // - try to use for only things like discrete layouts where the node position would change anyway
  elesfn$b.boundingBoxAt = function (fn) {
    var nodes = this.nodes();
    var cy = this.cy();
    var hasCompoundNodes = cy.hasCompoundNodes();
    var parents = cy.collection();
    if (hasCompoundNodes) {
      parents = nodes.filter(function (node) {
        return node.isParent();
      });
      nodes = nodes.not(parents);
    }
    if (plainObject(fn)) {
      var obj = fn;
      fn = function fn() {
        return obj;
      };
    }
    var storeOldPos = function storeOldPos(node, i) {
      return node._private.bbAtOldPos = fn(node, i);
    };
    var getOldPos = function getOldPos(node) {
      return node._private.bbAtOldPos;
    };
    cy.startBatch();
    nodes.forEach(storeOldPos).silentPositions(fn);
    if (hasCompoundNodes) {
      parents.dirtyCompoundBoundsCache();
      parents.dirtyBoundingBoxCache();
      parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle
    }

    var bb = copyBoundingBox(this.boundingBox({
      useCache: false
    }));
    nodes.silentPositions(getOldPos);
    if (hasCompoundNodes) {
      parents.dirtyCompoundBoundsCache();
      parents.dirtyBoundingBoxCache();
      parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle
    }

    cy.endBatch();
    return bb;
  };
  fn$3.boundingbox = fn$3.bb = fn$3.boundingBox;
  fn$3.renderedBoundingbox = fn$3.renderedBoundingBox;
  var bounds = elesfn$b;

  var fn$2, elesfn$a;
  fn$2 = elesfn$a = {};
  var defineDimFns = function defineDimFns(opts) {
    opts.uppercaseName = capitalize(opts.name);
    opts.autoName = 'auto' + opts.uppercaseName;
    opts.labelName = 'label' + opts.uppercaseName;
    opts.outerName = 'outer' + opts.uppercaseName;
    opts.uppercaseOuterName = capitalize(opts.outerName);
    fn$2[opts.name] = function dimImpl() {
      var ele = this[0];
      var _p = ele._private;
      var cy = _p.cy;
      var styleEnabled = cy._private.styleEnabled;
      if (ele) {
        if (styleEnabled) {
          if (ele.isParent()) {
            ele.updateCompoundBounds();
            return _p[opts.autoName] || 0;
          }
          var d = ele.pstyle(opts.name);
          switch (d.strValue) {
            case 'label':
              ele.recalculateRenderedStyle();
              return _p.rstyle[opts.labelName] || 0;
            default:
              return d.pfValue;
          }
        } else {
          return 1;
        }
      }
    };
    fn$2['outer' + opts.uppercaseName] = function outerDimImpl() {
      var ele = this[0];
      var _p = ele._private;
      var cy = _p.cy;
      var styleEnabled = cy._private.styleEnabled;
      if (ele) {
        if (styleEnabled) {
          var dim = ele[opts.name]();
          var border = ele.pstyle('border-width').pfValue; // n.b. 1/2 each side
          var padding = 2 * ele.padding();
          return dim + border + padding;
        } else {
          return 1;
        }
      }
    };
    fn$2['rendered' + opts.uppercaseName] = function renderedDimImpl() {
      var ele = this[0];
      if (ele) {
        var d = ele[opts.name]();
        return d * this.cy().zoom();
      }
    };
    fn$2['rendered' + opts.uppercaseOuterName] = function renderedOuterDimImpl() {
      var ele = this[0];
      if (ele) {
        var od = ele[opts.outerName]();
        return od * this.cy().zoom();
      }
    };
  };
  defineDimFns({
    name: 'width'
  });
  defineDimFns({
    name: 'height'
  });
  elesfn$a.padding = function () {
    var ele = this[0];
    var _p = ele._private;
    if (ele.isParent()) {
      ele.updateCompoundBounds();
      if (_p.autoPadding !== undefined) {
        return _p.autoPadding;
      } else {
        return ele.pstyle('padding').pfValue;
      }
    } else {
      return ele.pstyle('padding').pfValue;
    }
  };
  elesfn$a.paddedHeight = function () {
    var ele = this[0];
    return ele.height() + 2 * ele.padding();
  };
  elesfn$a.paddedWidth = function () {
    var ele = this[0];
    return ele.width() + 2 * ele.padding();
  };
  var widthHeight = elesfn$a;

  var ifEdge = function ifEdge(ele, getValue) {
    if (ele.isEdge()) {
      return getValue(ele);
    }
  };
  var ifEdgeRenderedPosition = function ifEdgeRenderedPosition(ele, getPoint) {
    if (ele.isEdge()) {
      var cy = ele.cy();
      return modelToRenderedPosition(getPoint(ele), cy.zoom(), cy.pan());
    }
  };
  var ifEdgeRenderedPositions = function ifEdgeRenderedPositions(ele, getPoints) {
    if (ele.isEdge()) {
      var cy = ele.cy();
      var pan = cy.pan();
      var zoom = cy.zoom();
      return getPoints(ele).map(function (p) {
        return modelToRenderedPosition(p, zoom, pan);
      });
    }
  };
  var controlPoints = function controlPoints(ele) {
    return ele.renderer().getControlPoints(ele);
  };
  var segmentPoints = function segmentPoints(ele) {
    return ele.renderer().getSegmentPoints(ele);
  };
  var sourceEndpoint = function sourceEndpoint(ele) {
    return ele.renderer().getSourceEndpoint(ele);
  };
  var targetEndpoint = function targetEndpoint(ele) {
    return ele.renderer().getTargetEndpoint(ele);
  };
  var midpoint = function midpoint(ele) {
    return ele.renderer().getEdgeMidpoint(ele);
  };
  var pts = {
    controlPoints: {
      get: controlPoints,
      mult: true
    },
    segmentPoints: {
      get: segmentPoints,
      mult: true
    },
    sourceEndpoint: {
      get: sourceEndpoint
    },
    targetEndpoint: {
      get: targetEndpoint
    },
    midpoint: {
      get: midpoint
    }
  };
  var renderedName = function renderedName(name) {
    return 'rendered' + name[0].toUpperCase() + name.substr(1);
  };
  var edgePoints = Object.keys(pts).reduce(function (obj, name) {
    var spec = pts[name];
    var rName = renderedName(name);
    obj[name] = function () {
      return ifEdge(this, spec.get);
    };
    if (spec.mult) {
      obj[rName] = function () {
        return ifEdgeRenderedPositions(this, spec.get);
      };
    } else {
      obj[rName] = function () {
        return ifEdgeRenderedPosition(this, spec.get);
      };
    }
    return obj;
  }, {});

  var dimensions = extend({}, position, bounds, widthHeight, edgePoints);

  /*!
  Event object based on jQuery events, MIT license

  https://jquery.org/license/
  https://tldrlegal.com/license/mit-license
  https://github.com/jquery/jquery/blob/master/src/event.js
  */

  var Event = function Event(src, props) {
    this.recycle(src, props);
  };
  function returnFalse() {
    return false;
  }
  function returnTrue() {
    return true;
  }

  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  Event.prototype = {
    instanceString: function instanceString() {
      return 'event';
    },
    recycle: function recycle(src, props) {
      this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = returnFalse;
      if (src != null && src.preventDefault) {
        // Browser Event object
        this.type = src.type;

        // Events bubbling up the document may have been marked as prevented
        // by a handler lower down the tree; reflect the correct value.
        this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse;
      } else if (src != null && src.type) {
        // Plain object containing all event details
        props = src;
      } else {
        // Event string
        this.type = src;
      }

      // Put explicitly provided properties onto the event object
      if (props != null) {
        // more efficient to manually copy fields we use
        this.originalEvent = props.originalEvent;
        this.type = props.type != null ? props.type : this.type;
        this.cy = props.cy;
        this.target = props.target;
        this.position = props.position;
        this.renderedPosition = props.renderedPosition;
        this.namespace = props.namespace;
        this.layout = props.layout;
      }
      if (this.cy != null && this.position != null && this.renderedPosition == null) {
        // create a rendered position based on the passed position
        var pos = this.position;
        var zoom = this.cy.zoom();
        var pan = this.cy.pan();
        this.renderedPosition = {
          x: pos.x * zoom + pan.x,
          y: pos.y * zoom + pan.y
        };
      }

      // Create a timestamp if incoming event doesn't have one
      this.timeStamp = src && src.timeStamp || Date.now();
    },
    preventDefault: function preventDefault() {
      this.isDefaultPrevented = returnTrue;
      var e = this.originalEvent;
      if (!e) {
        return;
      }

      // if preventDefault exists run it on the original event
      if (e.preventDefault) {
        e.preventDefault();
      }
    },
    stopPropagation: function stopPropagation() {
      this.isPropagationStopped = returnTrue;
      var e = this.originalEvent;
      if (!e) {
        return;
      }

      // if stopPropagation exists run it on the original event
      if (e.stopPropagation) {
        e.stopPropagation();
      }
    },
    stopImmediatePropagation: function stopImmediatePropagation() {
      this.isImmediatePropagationStopped = returnTrue;
      this.stopPropagation();
    },
    isDefaultPrevented: returnFalse,
    isPropagationStopped: returnFalse,
    isImmediatePropagationStopped: returnFalse
  };

  var eventRegex = /^([^.]+)(\.(?:[^.]+))?$/; // regex for matching event strings (e.g. "click.namespace")
  var universalNamespace = '.*'; // matches as if no namespace specified and prevents users from unbinding accidentally

  var defaults$8 = {
    qualifierCompare: function qualifierCompare(q1, q2) {
      return q1 === q2;
    },
    eventMatches: function eventMatches( /*context, listener, eventObj*/
    ) {
      return true;
    },
    addEventFields: function addEventFields( /*context, evt*/
    ) {},
    callbackContext: function callbackContext(context /*, listener, eventObj*/) {
      return context;
    },
    beforeEmit: function beforeEmit( /* context, listener, eventObj */
    ) {},
    afterEmit: function afterEmit( /* context, listener, eventObj */
    ) {},
    bubble: function bubble( /*context*/
    ) {
      return false;
    },
    parent: function parent( /*context*/
    ) {
      return null;
    },
    context: null
  };
  var defaultsKeys = Object.keys(defaults$8);
  var emptyOpts = {};
  function Emitter() {
    var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyOpts;
    var context = arguments.length > 1 ? arguments[1] : undefined;
    // micro-optimisation vs Object.assign() -- reduces Element instantiation time
    for (var i = 0; i < defaultsKeys.length; i++) {
      var key = defaultsKeys[i];
      this[key] = opts[key] || defaults$8[key];
    }
    this.context = context || this.context;
    this.listeners = [];
    this.emitting = 0;
  }
  var p = Emitter.prototype;
  var forEachEvent = function forEachEvent(self, handler, events, qualifier, callback, conf, confOverrides) {
    if (fn$6(qualifier)) {
      callback = qualifier;
      qualifier = null;
    }
    if (confOverrides) {
      if (conf == null) {
        conf = confOverrides;
      } else {
        conf = extend({}, conf, confOverrides);
      }
    }
    var eventList = array(events) ? events : events.split(/\s+/);
    for (var i = 0; i < eventList.length; i++) {
      var evt = eventList[i];
      if (emptyString(evt)) {
        continue;
      }
      var match = evt.match(eventRegex); // type[.namespace]

      if (match) {
        var type = match[1];
        var namespace = match[2] ? match[2] : null;
        var ret = handler(self, evt, type, namespace, qualifier, callback, conf);
        if (ret === false) {
          break;
        } // allow exiting early
      }
    }
  };

  var makeEventObj = function makeEventObj(self, obj) {
    self.addEventFields(self.context, obj);
    return new Event(obj.type, obj);
  };
  var forEachEventObj = function forEachEventObj(self, handler, events) {
    if (event(events)) {
      handler(self, events);
      return;
    } else if (plainObject(events)) {
      handler(self, makeEventObj(self, events));
      return;
    }
    var eventList = array(events) ? events : events.split(/\s+/);
    for (var i = 0; i < eventList.length; i++) {
      var evt = eventList[i];
      if (emptyString(evt)) {
        continue;
      }
      var match = evt.match(eventRegex); // type[.namespace]

      if (match) {
        var type = match[1];
        var namespace = match[2] ? match[2] : null;
        var eventObj = makeEventObj(self, {
          type: type,
          namespace: namespace,
          target: self.context
        });
        handler(self, eventObj);
      }
    }
  };
  p.on = p.addListener = function (events, qualifier, callback, conf, confOverrides) {
    forEachEvent(this, function (self, event, type, namespace, qualifier, callback, conf) {
      if (fn$6(callback)) {
        self.listeners.push({
          event: event,
          // full event string
          callback: callback,
          // callback to run
          type: type,
          // the event type (e.g. 'click')
          namespace: namespace,
          // the event namespace (e.g. ".foo")
          qualifier: qualifier,
          // a restriction on whether to match this emitter
          conf: conf // additional configuration
        });
      }
    }, events, qualifier, callback, conf, confOverrides);
    return this;
  };
  p.one = function (events, qualifier, callback, conf) {
    return this.on(events, qualifier, callback, conf, {
      one: true
    });
  };
  p.removeListener = p.off = function (events, qualifier, callback, conf) {
    var _this = this;
    if (this.emitting !== 0) {
      this.listeners = copyArray$1(this.listeners);
    }
    var listeners = this.listeners;
    var _loop = function _loop(i) {
      var listener = listeners[i];
      forEachEvent(_this, function (self, event, type, namespace, qualifier, callback /*, conf*/) {
        if ((listener.type === type || events === '*') && (!namespace && listener.namespace !== '.*' || listener.namespace === namespace) && (!qualifier || self.qualifierCompare(listener.qualifier, qualifier)) && (!callback || listener.callback === callback)) {
          listeners.splice(i, 1);
          return false;
        }
      }, events, qualifier, callback, conf);
    };
    for (var i = listeners.length - 1; i >= 0; i--) {
      _loop(i);
    }
    return this;
  };
  p.removeAllListeners = function () {
    return this.removeListener('*');
  };
  p.emit = p.trigger = function (events, extraParams, manualCallback) {
    var listeners = this.listeners;
    var numListenersBeforeEmit = listeners.length;
    this.emitting++;
    if (!array(extraParams)) {
      extraParams = [extraParams];
    }
    forEachEventObj(this, function (self, eventObj) {
      if (manualCallback != null) {
        listeners = [{
          event: eventObj.event,
          type: eventObj.type,
          namespace: eventObj.namespace,
          callback: manualCallback
        }];
        numListenersBeforeEmit = listeners.length;
      }
      var _loop2 = function _loop2(i) {
        var listener = listeners[i];
        if (listener.type === eventObj.type && (!listener.namespace || listener.namespace === eventObj.namespace || listener.namespace === universalNamespace) && self.eventMatches(self.context, listener, eventObj)) {
          var args = [eventObj];
          if (extraParams != null) {
            push(args, extraParams);
          }
          self.beforeEmit(self.context, listener, eventObj);
          if (listener.conf && listener.conf.one) {
            self.listeners = self.listeners.filter(function (l) {
              return l !== listener;
            });
          }
          var context = self.callbackContext(self.context, listener, eventObj);
          var ret = listener.callback.apply(context, args);
          self.afterEmit(self.context, listener, eventObj);
          if (ret === false) {
            eventObj.stopPropagation();
            eventObj.preventDefault();
          }
        } // if listener matches
      };
      for (var i = 0; i < numListenersBeforeEmit; i++) {
        _loop2(i);
      } // for listener

      if (self.bubble(self.context) && !eventObj.isPropagationStopped()) {
        self.parent(self.context).emit(eventObj, extraParams);
      }
    }, events);
    this.emitting--;
    return this;
  };

  var emitterOptions$1 = {
    qualifierCompare: function qualifierCompare(selector1, selector2) {
      if (selector1 == null || selector2 == null) {
        return selector1 == null && selector2 == null;
      } else {
        return selector1.sameText(selector2);
      }
    },
    eventMatches: function eventMatches(ele, listener, eventObj) {
      var selector = listener.qualifier;
      if (selector != null) {
        return ele !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);
      }
      return true;
    },
    addEventFields: function addEventFields(ele, evt) {
      evt.cy = ele.cy();
      evt.target = ele;
    },
    callbackContext: function callbackContext(ele, listener, eventObj) {
      return listener.qualifier != null ? eventObj.target : ele;
    },
    beforeEmit: function beforeEmit(context, listener /*, eventObj*/) {
      if (listener.conf && listener.conf.once) {
        listener.conf.onceCollection.removeListener(listener.event, listener.qualifier, listener.callback);
      }
    },
    bubble: function bubble() {
      return true;
    },
    parent: function parent(ele) {
      return ele.isChild() ? ele.parent() : ele.cy();
    }
  };
  var argSelector$1 = function argSelector(arg) {
    if (string(arg)) {
      return new Selector(arg);
    } else {
      return arg;
    }
  };
  var elesfn$9 = {
    createEmitter: function createEmitter() {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var _p = ele._private;
        if (!_p.emitter) {
          _p.emitter = new Emitter(emitterOptions$1, ele);
        }
      }
      return this;
    },
    emitter: function emitter() {
      return this._private.emitter;
    },
    on: function on(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().on(events, argSel, callback);
      }
      return this;
    },
    removeListener: function removeListener(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().removeListener(events, argSel, callback);
      }
      return this;
    },
    removeAllListeners: function removeAllListeners() {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().removeAllListeners();
      }
      return this;
    },
    one: function one(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().one(events, argSel, callback);
      }
      return this;
    },
    once: function once(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().on(events, argSel, callback, {
          once: true,
          onceCollection: this
        });
      }
    },
    emit: function emit(events, extraParams) {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().emit(events, extraParams);
      }
      return this;
    },
    emitAndNotify: function emitAndNotify(event, extraParams) {
      // for internal use only
      if (this.length === 0) {
        return;
      } // empty collections don't need to notify anything

      // notify renderer
      this.cy().notify(event, this);
      this.emit(event, extraParams);
      return this;
    }
  };
  define.eventAliasesOn(elesfn$9);

  var elesfn$8 = {
    nodes: function nodes(selector) {
      return this.filter(function (ele) {
        return ele.isNode();
      }).filter(selector);
    },
    edges: function edges(selector) {
      return this.filter(function (ele) {
        return ele.isEdge();
      }).filter(selector);
    },
    // internal helper to get nodes and edges as separate collections with single iteration over elements
    byGroup: function byGroup() {
      var nodes = this.spawn();
      var edges = this.spawn();
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        if (ele.isNode()) {
          nodes.push(ele);
        } else {
          edges.push(ele);
        }
      }
      return {
        nodes: nodes,
        edges: edges
      };
    },
    filter: function filter(_filter, thisArg) {
      if (_filter === undefined) {
        // check this first b/c it's the most common/performant case
        return this;
      } else if (string(_filter) || elementOrCollection(_filter)) {
        return new Selector(_filter).filter(this);
      } else if (fn$6(_filter)) {
        var filterEles = this.spawn();
        var eles = this;
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var include = thisArg ? _filter.apply(thisArg, [ele, i, eles]) : _filter(ele, i, eles);
          if (include) {
            filterEles.push(ele);
          }
        }
        return filterEles;
      }
      return this.spawn(); // if not handled by above, give 'em an empty collection
    },

    not: function not(toRemove) {
      if (!toRemove) {
        return this;
      } else {
        if (string(toRemove)) {
          toRemove = this.filter(toRemove);
        }
        var elements = this.spawn();
        for (var i = 0; i < this.length; i++) {
          var element = this[i];
          var remove = toRemove.has(element);
          if (!remove) {
            elements.push(element);
          }
        }
        return elements;
      }
    },
    absoluteComplement: function absoluteComplement() {
      var cy = this.cy();
      return cy.mutableElements().not(this);
    },
    intersect: function intersect(other) {
      // if a selector is specified, then filter by it instead
      if (string(other)) {
        var selector = other;
        return this.filter(selector);
      }
      var elements = this.spawn();
      var col1 = this;
      var col2 = other;
      var col1Smaller = this.length < other.length;
      var colS = col1Smaller ? col1 : col2;
      var colL = col1Smaller ? col2 : col1;
      for (var i = 0; i < colS.length; i++) {
        var ele = colS[i];
        if (colL.has(ele)) {
          elements.push(ele);
        }
      }
      return elements;
    },
    xor: function xor(other) {
      var cy = this._private.cy;
      if (string(other)) {
        other = cy.$(other);
      }
      var elements = this.spawn();
      var col1 = this;
      var col2 = other;
      var add = function add(col, other) {
        for (var i = 0; i < col.length; i++) {
          var ele = col[i];
          var id = ele._private.data.id;
          var inOther = other.hasElementWithId(id);
          if (!inOther) {
            elements.push(ele);
          }
        }
      };
      add(col1, col2);
      add(col2, col1);
      return elements;
    },
    diff: function diff(other) {
      var cy = this._private.cy;
      if (string(other)) {
        other = cy.$(other);
      }
      var left = this.spawn();
      var right = this.spawn();
      var both = this.spawn();
      var col1 = this;
      var col2 = other;
      var add = function add(col, other, retEles) {
        for (var i = 0; i < col.length; i++) {
          var ele = col[i];
          var id = ele._private.data.id;
          var inOther = other.hasElementWithId(id);
          if (inOther) {
            both.merge(ele);
          } else {
            retEles.push(ele);
          }
        }
      };
      add(col1, col2, left);
      add(col2, col1, right);
      return {
        left: left,
        right: right,
        both: both
      };
    },
    add: function add(toAdd) {
      var cy = this._private.cy;
      if (!toAdd) {
        return this;
      }
      if (string(toAdd)) {
        var selector = toAdd;
        toAdd = cy.mutableElements().filter(selector);
      }
      var elements = this.spawnSelf();
      for (var i = 0; i < toAdd.length; i++) {
        var ele = toAdd[i];
        var add = !this.has(ele);
        if (add) {
          elements.push(ele);
        }
      }
      return elements;
    },
    // in place merge on calling collection
    merge: function merge(toAdd) {
      var _p = this._private;
      var cy = _p.cy;
      if (!toAdd) {
        return this;
      }
      if (toAdd && string(toAdd)) {
        var selector = toAdd;
        toAdd = cy.mutableElements().filter(selector);
      }
      var map = _p.map;
      for (var i = 0; i < toAdd.length; i++) {
        var toAddEle = toAdd[i];
        var id = toAddEle._private.data.id;
        var add = !map.has(id);
        if (add) {
          var index = this.length++;
          this[index] = toAddEle;
          map.set(id, {
            ele: toAddEle,
            index: index
          });
        }
      }
      return this; // chaining
    },

    unmergeAt: function unmergeAt(i) {
      var ele = this[i];
      var id = ele.id();
      var _p = this._private;
      var map = _p.map;

      // remove ele
      this[i] = undefined;
      map["delete"](id);
      var unmergedLastEle = i === this.length - 1;

      // replace empty spot with last ele in collection
      if (this.length > 1 && !unmergedLastEle) {
        var lastEleI = this.length - 1;
        var lastEle = this[lastEleI];
        var lastEleId = lastEle._private.data.id;
        this[lastEleI] = undefined;
        this[i] = lastEle;
        map.set(lastEleId, {
          ele: lastEle,
          index: i
        });
      }

      // the collection is now 1 ele smaller
      this.length--;
      return this;
    },
    // remove single ele in place in calling collection
    unmergeOne: function unmergeOne(ele) {
      ele = ele[0];
      var _p = this._private;
      var id = ele._private.data.id;
      var map = _p.map;
      var entry = map.get(id);
      if (!entry) {
        return this; // no need to remove
      }

      var i = entry.index;
      this.unmergeAt(i);
      return this;
    },
    // remove eles in place on calling collection
    unmerge: function unmerge(toRemove) {
      var cy = this._private.cy;
      if (!toRemove) {
        return this;
      }
      if (toRemove && string(toRemove)) {
        var selector = toRemove;
        toRemove = cy.mutableElements().filter(selector);
      }
      for (var i = 0; i < toRemove.length; i++) {
        this.unmergeOne(toRemove[i]);
      }
      return this; // chaining
    },

    unmergeBy: function unmergeBy(toRmFn) {
      for (var i = this.length - 1; i >= 0; i--) {
        var ele = this[i];
        if (toRmFn(ele)) {
          this.unmergeAt(i);
        }
      }
      return this;
    },
    map: function map(mapFn, thisArg) {
      var arr = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var ret = thisArg ? mapFn.apply(thisArg, [ele, i, eles]) : mapFn(ele, i, eles);
        arr.push(ret);
      }
      return arr;
    },
    reduce: function reduce(fn, initialValue) {
      var val = initialValue;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        val = fn(val, eles[i], i, eles);
      }
      return val;
    },
    max: function max(valFn, thisArg) {
      var max = -Infinity;
      var maxEle;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);
        if (val > max) {
          max = val;
          maxEle = ele;
        }
      }
      return {
        value: max,
        ele: maxEle
      };
    },
    min: function min(valFn, thisArg) {
      var min = Infinity;
      var minEle;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);
        if (val < min) {
          min = val;
          minEle = ele;
        }
      }
      return {
        value: min,
        ele: minEle
      };
    }
  };

  // aliases
  var fn$1 = elesfn$8;
  fn$1['u'] = fn$1['|'] = fn$1['+'] = fn$1.union = fn$1.or = fn$1.add;
  fn$1['\\'] = fn$1['!'] = fn$1['-'] = fn$1.difference = fn$1.relativeComplement = fn$1.subtract = fn$1.not;
  fn$1['n'] = fn$1['&'] = fn$1['.'] = fn$1.and = fn$1.intersection = fn$1.intersect;
  fn$1['^'] = fn$1['(+)'] = fn$1['(-)'] = fn$1.symmetricDifference = fn$1.symdiff = fn$1.xor;
  fn$1.fnFilter = fn$1.filterFn = fn$1.stdFilter = fn$1.filter;
  fn$1.complement = fn$1.abscomp = fn$1.absoluteComplement;

  var elesfn$7 = {
    isNode: function isNode() {
      return this.group() === 'nodes';
    },
    isEdge: function isEdge() {
      return this.group() === 'edges';
    },
    isLoop: function isLoop() {
      return this.isEdge() && this.source()[0] === this.target()[0];
    },
    isSimple: function isSimple() {
      return this.isEdge() && this.source()[0] !== this.target()[0];
    },
    group: function group() {
      var ele = this[0];
      if (ele) {
        return ele._private.group;
      }
    }
  };

  /**
   *  Elements are drawn in a specific order based on compound depth (low to high), the element type (nodes above edges),
   *  and z-index (low to high).  These styles affect how this applies:
   *
   *  z-compound-depth: May be `bottom | orphan | auto | top`.  The first drawn is `bottom`, then `orphan` which is the
   *      same depth as the root of the compound graph, followed by the default value `auto` which draws in order from
   *      root to leaves of the compound graph.  The last drawn is `top`.
   *  z-index-compare: May be `auto | manual`.  The default value is `auto` which always draws edges under nodes.
   *      `manual` ignores this convention and draws based on the `z-index` value setting.
   *  z-index: An integer value that affects the relative draw order of elements.  In general, an element with a higher
   *      `z-index` will be drawn on top of an element with a lower `z-index`.
   */
  var zIndexSort = function zIndexSort(a, b) {
    var cy = a.cy();
    var hasCompoundNodes = cy.hasCompoundNodes();
    function getDepth(ele) {
      var style = ele.pstyle('z-compound-depth');
      if (style.value === 'auto') {
        return hasCompoundNodes ? ele.zDepth() : 0;
      } else if (style.value === 'bottom') {
        return -1;
      } else if (style.value === 'top') {
        return MAX_INT$1;
      }
      // 'orphan'
      return 0;
    }
    var depthDiff = getDepth(a) - getDepth(b);
    if (depthDiff !== 0) {
      return depthDiff;
    }
    function getEleDepth(ele) {
      var style = ele.pstyle('z-index-compare');
      if (style.value === 'auto') {
        return ele.isNode() ? 1 : 0;
      }
      // 'manual'
      return 0;
    }
    var eleDiff = getEleDepth(a) - getEleDepth(b);
    if (eleDiff !== 0) {
      return eleDiff;
    }
    var zDiff = a.pstyle('z-index').value - b.pstyle('z-index').value;
    if (zDiff !== 0) {
      return zDiff;
    }
    // compare indices in the core (order added to graph w/ last on top)
    return a.poolIndex() - b.poolIndex();
  };

  var elesfn$6 = {
    forEach: function forEach(fn, thisArg) {
      if (fn$6(fn)) {
        var N = this.length;
        for (var i = 0; i < N; i++) {
          var ele = this[i];
          var ret = thisArg ? fn.apply(thisArg, [ele, i, this]) : fn(ele, i, this);
          if (ret === false) {
            break;
          } // exit each early on return false
        }
      }

      return this;
    },
    toArray: function toArray() {
      var array = [];
      for (var i = 0; i < this.length; i++) {
        array.push(this[i]);
      }
      return array;
    },
    slice: function slice(start, end) {
      var array = [];
      var thisSize = this.length;
      if (end == null) {
        end = thisSize;
      }
      if (start == null) {
        start = 0;
      }
      if (start < 0) {
        start = thisSize + start;
      }
      if (end < 0) {
        end = thisSize + end;
      }
      for (var i = start; i >= 0 && i < end && i < thisSize; i++) {
        array.push(this[i]);
      }
      return this.spawn(array);
    },
    size: function size() {
      return this.length;
    },
    eq: function eq(i) {
      return this[i] || this.spawn();
    },
    first: function first() {
      return this[0] || this.spawn();
    },
    last: function last() {
      return this[this.length - 1] || this.spawn();
    },
    empty: function empty() {
      return this.length === 0;
    },
    nonempty: function nonempty() {
      return !this.empty();
    },
    sort: function sort(sortFn) {
      if (!fn$6(sortFn)) {
        return this;
      }
      var sorted = this.toArray().sort(sortFn);
      return this.spawn(sorted);
    },
    sortByZIndex: function sortByZIndex() {
      return this.sort(zIndexSort);
    },
    zDepth: function zDepth() {
      var ele = this[0];
      if (!ele) {
        return undefined;
      }

      // let cy = ele.cy();
      var _p = ele._private;
      var group = _p.group;
      if (group === 'nodes') {
        var depth = _p.data.parent ? ele.parents().size() : 0;
        if (!ele.isParent()) {
          return MAX_INT$1 - 1; // childless nodes always on top
        }

        return depth;
      } else {
        var src = _p.source;
        var tgt = _p.target;
        var srcDepth = src.zDepth();
        var tgtDepth = tgt.zDepth();
        return Math.max(srcDepth, tgtDepth, 0); // depth of deepest parent
      }
    }
  };

  elesfn$6.each = elesfn$6.forEach;
  var defineSymbolIterator = function defineSymbolIterator() {
    var typeofUndef = "undefined" ;
    var isIteratorSupported = (typeof Symbol === "undefined" ? "undefined" : _typeof(Symbol)) != typeofUndef && _typeof(Symbol.iterator) != typeofUndef; // eslint-disable-line no-undef

    if (isIteratorSupported) {
      elesfn$6[Symbol.iterator] = function () {
        var _this = this;
        // eslint-disable-line no-undef
        var entry = {
          value: undefined,
          done: false
        };
        var i = 0;
        var length = this.length;
        return _defineProperty$1({
          next: function next() {
            if (i < length) {
              entry.value = _this[i++];
            } else {
              entry.value = undefined;
              entry.done = true;
            }
            return entry;
          }
        }, Symbol.iterator, function () {
          // eslint-disable-line no-undef
          return this;
        });
      };
    }
  };
  defineSymbolIterator();

  var getLayoutDimensionOptions = defaults$g({
    nodeDimensionsIncludeLabels: false
  });
  var elesfn$5 = {
    // Calculates and returns node dimensions { x, y } based on options given
    layoutDimensions: function layoutDimensions(options) {
      options = getLayoutDimensionOptions(options);
      var dims;
      if (!this.takesUpSpace()) {
        dims = {
          w: 0,
          h: 0
        };
      } else if (options.nodeDimensionsIncludeLabels) {
        var bbDim = this.boundingBox();
        dims = {
          w: bbDim.w,
          h: bbDim.h
        };
      } else {
        dims = {
          w: this.outerWidth(),
          h: this.outerHeight()
        };
      }

      // sanitise the dimensions for external layouts (avoid division by zero)
      if (dims.w === 0 || dims.h === 0) {
        dims.w = dims.h = 1;
      }
      return dims;
    },
    // using standard layout options, apply position function (w/ or w/o animation)
    layoutPositions: function layoutPositions(layout, options, fn) {
      var nodes = this.nodes().filter(function (n) {
        return !n.isParent();
      });
      var cy = this.cy();
      var layoutEles = options.eles; // nodes & edges
      var getMemoizeKey = function getMemoizeKey(node) {
        return node.id();
      };
      var fnMem = memoize$1(fn, getMemoizeKey); // memoized version of position function

      layout.emit({
        type: 'layoutstart',
        layout: layout
      });
      layout.animations = [];
      var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) {
        var center = {
          x: nodesBb.x1 + nodesBb.w / 2,
          y: nodesBb.y1 + nodesBb.h / 2
        };
        var spacingVector = {
          // scale from center of bounding box (not necessarily 0,0)
          x: (pos.x - center.x) * spacing,
          y: (pos.y - center.y) * spacing
        };
        return {
          x: center.x + spacingVector.x,
          y: center.y + spacingVector.y
        };
      };
      var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1;
      var spacingBb = function spacingBb() {
        if (!useSpacingFactor) {
          return null;
        }
        var bb = makeBoundingBox();
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var pos = fnMem(node, i);
          expandBoundingBoxByPoint(bb, pos.x, pos.y);
        }
        return bb;
      };
      var bb = spacingBb();
      var getFinalPos = memoize$1(function (node, i) {
        var newPos = fnMem(node, i);
        if (useSpacingFactor) {
          var spacing = Math.abs(options.spacingFactor);
          newPos = calculateSpacing(spacing, bb, newPos);
        }
        if (options.transform != null) {
          newPos = options.transform(node, newPos);
        }
        return newPos;
      }, getMemoizeKey);
      if (options.animate) {
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var newPos = getFinalPos(node, i);
          var animateNode = options.animateFilter == null || options.animateFilter(node, i);
          if (animateNode) {
            var ani = node.animation({
              position: newPos,
              duration: options.animationDuration,
              easing: options.animationEasing
            });
            layout.animations.push(ani);
          } else {
            node.position(newPos);
          }
        }
        if (options.fit) {
          var fitAni = cy.animation({
            fit: {
              boundingBox: layoutEles.boundingBoxAt(getFinalPos),
              padding: options.padding
            },
            duration: options.animationDuration,
            easing: options.animationEasing
          });
          layout.animations.push(fitAni);
        } else if (options.zoom !== undefined && options.pan !== undefined) {
          var zoomPanAni = cy.animation({
            zoom: options.zoom,
            pan: options.pan,
            duration: options.animationDuration,
            easing: options.animationEasing
          });
          layout.animations.push(zoomPanAni);
        }
        layout.animations.forEach(function (ani) {
          return ani.play();
        });
        layout.one('layoutready', options.ready);
        layout.emit({
          type: 'layoutready',
          layout: layout
        });
        Promise$1.all(layout.animations.map(function (ani) {
          return ani.promise();
        })).then(function () {
          layout.one('layoutstop', options.stop);
          layout.emit({
            type: 'layoutstop',
            layout: layout
          });
        });
      } else {
        nodes.positions(getFinalPos);
        if (options.fit) {
          cy.fit(options.eles, options.padding);
        }
        if (options.zoom != null) {
          cy.zoom(options.zoom);
        }
        if (options.pan) {
          cy.pan(options.pan);
        }
        layout.one('layoutready', options.ready);
        layout.emit({
          type: 'layoutready',
          layout: layout
        });
        layout.one('layoutstop', options.stop);
        layout.emit({
          type: 'layoutstop',
          layout: layout
        });
      }
      return this; // chaining
    },

    layout: function layout(options) {
      var cy = this.cy();
      return cy.makeLayout(extend({}, options, {
        eles: this
      }));
    }
  };

  // aliases:
  elesfn$5.createLayout = elesfn$5.makeLayout = elesfn$5.layout;

  function styleCache(key, fn, ele) {
    var _p = ele._private;
    var cache = _p.styleCache = _p.styleCache || [];
    var val;
    if ((val = cache[key]) != null) {
      return val;
    } else {
      val = cache[key] = fn(ele);
      return val;
    }
  }
  function cacheStyleFunction(key, fn) {
    key = hashString(key);
    return function cachedStyleFunction(ele) {
      return styleCache(key, fn, ele);
    };
  }
  function cachePrototypeStyleFunction(key, fn) {
    key = hashString(key);
    var selfFn = function selfFn(ele) {
      return fn.call(ele);
    };
    return function cachedPrototypeStyleFunction() {
      var ele = this[0];
      if (ele) {
        return styleCache(key, selfFn, ele);
      }
    };
  }
  var elesfn$4 = {
    recalculateRenderedStyle: function recalculateRenderedStyle(useCache) {
      var cy = this.cy();
      var renderer = cy.renderer();
      var styleEnabled = cy.styleEnabled();
      if (renderer && styleEnabled) {
        renderer.recalculateRenderedStyle(this, useCache);
      }
      return this;
    },
    dirtyStyleCache: function dirtyStyleCache() {
      var cy = this.cy();
      var dirty = function dirty(ele) {
        return ele._private.styleCache = null;
      };
      if (cy.hasCompoundNodes()) {
        var eles;
        eles = this.spawnSelf().merge(this.descendants()).merge(this.parents());
        eles.merge(eles.connectedEdges());
        eles.forEach(dirty);
      } else {
        this.forEach(function (ele) {
          dirty(ele);
          ele.connectedEdges().forEach(dirty);
        });
      }
      return this;
    },
    // fully updates (recalculates) the style for the elements
    updateStyle: function updateStyle(notifyRenderer) {
      var cy = this._private.cy;
      if (!cy.styleEnabled()) {
        return this;
      }
      if (cy.batching()) {
        var bEles = cy._private.batchStyleEles;
        bEles.merge(this);
        return this; // chaining and exit early when batching
      }

      var hasCompounds = cy.hasCompoundNodes();
      var updatedEles = this;
      notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
      if (hasCompounds) {
        // then add everything up and down for compound selector checks
        updatedEles = this.spawnSelf().merge(this.descendants()).merge(this.parents());
      }

      // let changedEles = style.apply( updatedEles );
      var changedEles = updatedEles;
      if (notifyRenderer) {
        changedEles.emitAndNotify('style'); // let renderer know we changed style
      } else {
        changedEles.emit('style'); // just fire the event
      }

      updatedEles.forEach(function (ele) {
        return ele._private.styleDirty = true;
      });
      return this; // chaining
    },

    // private: clears dirty flag and recalculates style
    cleanStyle: function cleanStyle() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return;
      }
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        if (ele._private.styleDirty) {
          // n.b. this flag should be set before apply() to avoid potential infinite recursion
          ele._private.styleDirty = false;
          cy.style().apply(ele);
        }
      }
    },
    // get the internal parsed style object for the specified property
    parsedStyle: function parsedStyle(property) {
      var includeNonDefault = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var ele = this[0];
      var cy = ele.cy();
      if (!cy.styleEnabled()) {
        return;
      }
      if (ele) {
        this.cleanStyle();
        var overriddenStyle = ele._private.style[property];
        if (overriddenStyle != null) {
          return overriddenStyle;
        } else if (includeNonDefault) {
          return cy.style().getDefaultProperty(property);
        } else {
          return null;
        }
      }
    },
    numericStyle: function numericStyle(property) {
      var ele = this[0];
      if (!ele.cy().styleEnabled()) {
        return;
      }
      if (ele) {
        var pstyle = ele.pstyle(property);
        return pstyle.pfValue !== undefined ? pstyle.pfValue : pstyle.value;
      }
    },
    numericStyleUnits: function numericStyleUnits(property) {
      var ele = this[0];
      if (!ele.cy().styleEnabled()) {
        return;
      }
      if (ele) {
        return ele.pstyle(property).units;
      }
    },
    // get the specified css property as a rendered value (i.e. on-screen value)
    // or get the whole rendered style if no property specified (NB doesn't allow setting)
    renderedStyle: function renderedStyle(property) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var ele = this[0];
      if (ele) {
        return cy.style().getRenderedStyle(ele, property);
      }
    },
    // read the calculated css style of the element or override the style (via a bypass)
    style: function style(name, value) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var updateTransitions = false;
      var style = cy.style();
      if (plainObject(name)) {
        // then extend the bypass
        var props = name;
        style.applyBypass(this, props, updateTransitions);
        this.emitAndNotify('style'); // let the renderer know we've updated style
      } else if (string(name)) {
        if (value === undefined) {
          // then get the property from the style
          var ele = this[0];
          if (ele) {
            return style.getStylePropertyValue(ele, name);
          } else {
            // empty collection => can't get any value
            return;
          }
        } else {
          // then set the bypass with the property value
          style.applyBypass(this, name, value, updateTransitions);
          this.emitAndNotify('style'); // let the renderer know we've updated style
        }
      } else if (name === undefined) {
        var _ele = this[0];
        if (_ele) {
          return style.getRawStyle(_ele);
        } else {
          // empty collection => can't get any value
          return;
        }
      }
      return this; // chaining
    },

    removeStyle: function removeStyle(names) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var updateTransitions = false;
      var style = cy.style();
      var eles = this;
      if (names === undefined) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          style.removeAllBypasses(ele, updateTransitions);
        }
      } else {
        names = names.split(/\s+/);
        for (var _i = 0; _i < eles.length; _i++) {
          var _ele2 = eles[_i];
          style.removeBypasses(_ele2, names, updateTransitions);
        }
      }
      this.emitAndNotify('style'); // let the renderer know we've updated style

      return this; // chaining
    },

    show: function show() {
      this.css('display', 'element');
      return this; // chaining
    },

    hide: function hide() {
      this.css('display', 'none');
      return this; // chaining
    },

    effectiveOpacity: function effectiveOpacity() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return 1;
      }
      var hasCompoundNodes = cy.hasCompoundNodes();
      var ele = this[0];
      if (ele) {
        var _p = ele._private;
        var parentOpacity = ele.pstyle('opacity').value;
        if (!hasCompoundNodes) {
          return parentOpacity;
        }
        var parents = !_p.data.parent ? null : ele.parents();
        if (parents) {
          for (var i = 0; i < parents.length; i++) {
            var parent = parents[i];
            var opacity = parent.pstyle('opacity').value;
            parentOpacity = opacity * parentOpacity;
          }
        }
        return parentOpacity;
      }
    },
    transparent: function transparent() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return false;
      }
      var ele = this[0];
      var hasCompoundNodes = ele.cy().hasCompoundNodes();
      if (ele) {
        if (!hasCompoundNodes) {
          return ele.pstyle('opacity').value === 0;
        } else {
          return ele.effectiveOpacity() === 0;
        }
      }
    },
    backgrounding: function backgrounding() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return false;
      }
      var ele = this[0];
      return ele._private.backgrounding ? true : false;
    }
  };
  function checkCompound(ele, parentOk) {
    var _p = ele._private;
    var parents = _p.data.parent ? ele.parents() : null;
    if (parents) {
      for (var i = 0; i < parents.length; i++) {
        var parent = parents[i];
        if (!parentOk(parent)) {
          return false;
        }
      }
    }
    return true;
  }
  function defineDerivedStateFunction(specs) {
    var ok = specs.ok;
    var edgeOkViaNode = specs.edgeOkViaNode || specs.ok;
    var parentOk = specs.parentOk || specs.ok;
    return function () {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return true;
      }
      var ele = this[0];
      var hasCompoundNodes = cy.hasCompoundNodes();
      if (ele) {
        var _p = ele._private;
        if (!ok(ele)) {
          return false;
        }
        if (ele.isNode()) {
          return !hasCompoundNodes || checkCompound(ele, parentOk);
        } else {
          var src = _p.source;
          var tgt = _p.target;
          return edgeOkViaNode(src) && (!hasCompoundNodes || checkCompound(src, edgeOkViaNode)) && (src === tgt || edgeOkViaNode(tgt) && (!hasCompoundNodes || checkCompound(tgt, edgeOkViaNode)));
        }
      }
    };
  }
  var eleTakesUpSpace = cacheStyleFunction('eleTakesUpSpace', function (ele) {
    return ele.pstyle('display').value === 'element' && ele.width() !== 0 && (ele.isNode() ? ele.height() !== 0 : true);
  });
  elesfn$4.takesUpSpace = cachePrototypeStyleFunction('takesUpSpace', defineDerivedStateFunction({
    ok: eleTakesUpSpace
  }));
  var eleInteractive = cacheStyleFunction('eleInteractive', function (ele) {
    return ele.pstyle('events').value === 'yes' && ele.pstyle('visibility').value === 'visible' && eleTakesUpSpace(ele);
  });
  var parentInteractive = cacheStyleFunction('parentInteractive', function (parent) {
    return parent.pstyle('visibility').value === 'visible' && eleTakesUpSpace(parent);
  });
  elesfn$4.interactive = cachePrototypeStyleFunction('interactive', defineDerivedStateFunction({
    ok: eleInteractive,
    parentOk: parentInteractive,
    edgeOkViaNode: eleTakesUpSpace
  }));
  elesfn$4.noninteractive = function () {
    var ele = this[0];
    if (ele) {
      return !ele.interactive();
    }
  };
  var eleVisible = cacheStyleFunction('eleVisible', function (ele) {
    return ele.pstyle('visibility').value === 'visible' && ele.pstyle('opacity').pfValue !== 0 && eleTakesUpSpace(ele);
  });
  var edgeVisibleViaNode = eleTakesUpSpace;
  elesfn$4.visible = cachePrototypeStyleFunction('visible', defineDerivedStateFunction({
    ok: eleVisible,
    edgeOkViaNode: edgeVisibleViaNode
  }));
  elesfn$4.hidden = function () {
    var ele = this[0];
    if (ele) {
      return !ele.visible();
    }
  };
  elesfn$4.isBundledBezier = cachePrototypeStyleFunction('isBundledBezier', function () {
    if (!this.cy().styleEnabled()) {
      return false;
    }
    return !this.removed() && this.pstyle('curve-style').value === 'bezier' && this.takesUpSpace();
  });
  elesfn$4.bypass = elesfn$4.css = elesfn$4.style;
  elesfn$4.renderedCss = elesfn$4.renderedStyle;
  elesfn$4.removeBypass = elesfn$4.removeCss = elesfn$4.removeStyle;
  elesfn$4.pstyle = elesfn$4.parsedStyle;

  var elesfn$3 = {};
  function defineSwitchFunction(params) {
    return function () {
      var args = arguments;
      var changedEles = [];

      // e.g. cy.nodes().select( data, handler )
      if (args.length === 2) {
        var data = args[0];
        var handler = args[1];
        this.on(params.event, data, handler);
      }

      // e.g. cy.nodes().select( handler )
      else if (args.length === 1 && fn$6(args[0])) {
        var _handler = args[0];
        this.on(params.event, _handler);
      }

      // e.g. cy.nodes().select()
      // e.g. (private) cy.nodes().select(['tapselect'])
      else if (args.length === 0 || args.length === 1 && array(args[0])) {
        var addlEvents = args.length === 1 ? args[0] : null;
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];
          var able = !params.ableField || ele._private[params.ableField];
          var changed = ele._private[params.field] != params.value;
          if (params.overrideAble) {
            var overrideAble = params.overrideAble(ele);
            if (overrideAble !== undefined) {
              able = overrideAble;
              if (!overrideAble) {
                return this;
              } // to save cycles assume not able for all on override
            }
          }

          if (able) {
            ele._private[params.field] = params.value;
            if (changed) {
              changedEles.push(ele);
            }
          }
        }
        var changedColl = this.spawn(changedEles);
        changedColl.updateStyle(); // change of state => possible change of style
        changedColl.emit(params.event);
        if (addlEvents) {
          changedColl.emit(addlEvents);
        }
      }
      return this;
    };
  }
  function defineSwitchSet(params) {
    elesfn$3[params.field] = function () {
      var ele = this[0];
      if (ele) {
        if (params.overrideField) {
          var val = params.overrideField(ele);
          if (val !== undefined) {
            return val;
          }
        }
        return ele._private[params.field];
      }
    };
    elesfn$3[params.on] = defineSwitchFunction({
      event: params.on,
      field: params.field,
      ableField: params.ableField,
      overrideAble: params.overrideAble,
      value: true
    });
    elesfn$3[params.off] = defineSwitchFunction({
      event: params.off,
      field: params.field,
      ableField: params.ableField,
      overrideAble: params.overrideAble,
      value: false
    });
  }
  defineSwitchSet({
    field: 'locked',
    overrideField: function overrideField(ele) {
      return ele.cy().autolock() ? true : undefined;
    },
    on: 'lock',
    off: 'unlock'
  });
  defineSwitchSet({
    field: 'grabbable',
    overrideField: function overrideField(ele) {
      return ele.cy().autoungrabify() || ele.pannable() ? false : undefined;
    },
    on: 'grabify',
    off: 'ungrabify'
  });
  defineSwitchSet({
    field: 'selected',
    ableField: 'selectable',
    overrideAble: function overrideAble(ele) {
      return ele.cy().autounselectify() ? false : undefined;
    },
    on: 'select',
    off: 'unselect'
  });
  defineSwitchSet({
    field: 'selectable',
    overrideField: function overrideField(ele) {
      return ele.cy().autounselectify() ? false : undefined;
    },
    on: 'selectify',
    off: 'unselectify'
  });
  elesfn$3.deselect = elesfn$3.unselect;
  elesfn$3.grabbed = function () {
    var ele = this[0];
    if (ele) {
      return ele._private.grabbed;
    }
  };
  defineSwitchSet({
    field: 'active',
    on: 'activate',
    off: 'unactivate'
  });
  defineSwitchSet({
    field: 'pannable',
    on: 'panify',
    off: 'unpanify'
  });
  elesfn$3.inactive = function () {
    var ele = this[0];
    if (ele) {
      return !ele._private.active;
    }
  };

  var elesfn$2 = {};

  // DAG functions
  ////////////////

  var defineDagExtremity = function defineDagExtremity(params) {
    return function dagExtremityImpl(selector) {
      var eles = this;
      var ret = [];
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        if (!ele.isNode()) {
          continue;
        }
        var disqualified = false;
        var edges = ele.connectedEdges();
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          var src = edge.source();
          var tgt = edge.target();
          if (params.noIncomingEdges && tgt === ele && src !== ele || params.noOutgoingEdges && src === ele && tgt !== ele) {
            disqualified = true;
            break;
          }
        }
        if (!disqualified) {
          ret.push(ele);
        }
      }
      return this.spawn(ret, true).filter(selector);
    };
  };
  var defineDagOneHop = function defineDagOneHop(params) {
    return function (selector) {
      var eles = this;
      var oEles = [];
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        if (!ele.isNode()) {
          continue;
        }
        var edges = ele.connectedEdges();
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          var src = edge.source();
          var tgt = edge.target();
          if (params.outgoing && src === ele) {
            oEles.push(edge);
            oEles.push(tgt);
          } else if (params.incoming && tgt === ele) {
            oEles.push(edge);
            oEles.push(src);
          }
        }
      }
      return this.spawn(oEles, true).filter(selector);
    };
  };
  var defineDagAllHops = function defineDagAllHops(params) {
    return function (selector) {
      var eles = this;
      var sEles = [];
      var sElesIds = {};
      for (;;) {
        var next = params.outgoing ? eles.outgoers() : eles.incomers();
        if (next.length === 0) {
          break;
        } // done if none left

        var newNext = false;
        for (var i = 0; i < next.length; i++) {
          var n = next[i];
          var nid = n.id();
          if (!sElesIds[nid]) {
            sElesIds[nid] = true;
            sEles.push(n);
            newNext = true;
          }
        }
        if (!newNext) {
          break;
        } // done if touched all outgoers already

        eles = next;
      }
      return this.spawn(sEles, true).filter(selector);
    };
  };
  elesfn$2.clearTraversalCache = function () {
    for (var i = 0; i < this.length; i++) {
      this[i]._private.traversalCache = null;
    }
  };
  extend(elesfn$2, {
    // get the root nodes in the DAG
    roots: defineDagExtremity({
      noIncomingEdges: true
    }),
    // get the leaf nodes in the DAG
    leaves: defineDagExtremity({
      noOutgoingEdges: true
    }),
    // normally called children in graph theory
    // these nodes =edges=> outgoing nodes
    outgoers: cache(defineDagOneHop({
      outgoing: true
    }), 'outgoers'),
    // aka DAG descendants
    successors: defineDagAllHops({
      outgoing: true
    }),
    // normally called parents in graph theory
    // these nodes <=edges= incoming nodes
    incomers: cache(defineDagOneHop({
      incoming: true
    }), 'incomers'),
    // aka DAG ancestors
    predecessors: defineDagAllHops({
      incoming: true
    })
  });

  // Neighbourhood functions
  //////////////////////////

  extend(elesfn$2, {
    neighborhood: cache(function (selector) {
      var elements = [];
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        // for all nodes
        var node = nodes[i];
        var connectedEdges = node.connectedEdges();

        // for each connected edge, add the edge and the other node
        for (var j = 0; j < connectedEdges.length; j++) {
          var edge = connectedEdges[j];
          var src = edge.source();
          var tgt = edge.target();
          var otherNode = node === src ? tgt : src;

          // need check in case of loop
          if (otherNode.length > 0) {
            elements.push(otherNode[0]); // add node 1 hop away
          }

          // add connected edge
          elements.push(edge[0]);
        }
      }
      return this.spawn(elements, true).filter(selector);
    }, 'neighborhood'),
    closedNeighborhood: function closedNeighborhood(selector) {
      return this.neighborhood().add(this).filter(selector);
    },
    openNeighborhood: function openNeighborhood(selector) {
      return this.neighborhood(selector);
    }
  });

  // aliases
  elesfn$2.neighbourhood = elesfn$2.neighborhood;
  elesfn$2.closedNeighbourhood = elesfn$2.closedNeighborhood;
  elesfn$2.openNeighbourhood = elesfn$2.openNeighborhood;

  // Edge functions
  /////////////////

  extend(elesfn$2, {
    source: cache(function sourceImpl(selector) {
      var ele = this[0];
      var src;
      if (ele) {
        src = ele._private.source || ele.cy().collection();
      }
      return src && selector ? src.filter(selector) : src;
    }, 'source'),
    target: cache(function targetImpl(selector) {
      var ele = this[0];
      var tgt;
      if (ele) {
        tgt = ele._private.target || ele.cy().collection();
      }
      return tgt && selector ? tgt.filter(selector) : tgt;
    }, 'target'),
    sources: defineSourceFunction({
      attr: 'source'
    }),
    targets: defineSourceFunction({
      attr: 'target'
    })
  });
  function defineSourceFunction(params) {
    return function sourceImpl(selector) {
      var sources = [];
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var src = ele._private[params.attr];
        if (src) {
          sources.push(src);
        }
      }
      return this.spawn(sources, true).filter(selector);
    };
  }
  extend(elesfn$2, {
    edgesWith: cache(defineEdgesWithFunction(), 'edgesWith'),
    edgesTo: cache(defineEdgesWithFunction({
      thisIsSrc: true
    }), 'edgesTo')
  });
  function defineEdgesWithFunction(params) {
    return function edgesWithImpl(otherNodes) {
      var elements = [];
      var cy = this._private.cy;
      var p = params || {};

      // get elements if a selector is specified
      if (string(otherNodes)) {
        otherNodes = cy.$(otherNodes);
      }
      for (var h = 0; h < otherNodes.length; h++) {
        var edges = otherNodes[h]._private.edges;
        for (var i = 0; i < edges.length; i++) {
          var edge = edges[i];
          var edgeData = edge._private.data;
          var thisToOther = this.hasElementWithId(edgeData.source) && otherNodes.hasElementWithId(edgeData.target);
          var otherToThis = otherNodes.hasElementWithId(edgeData.source) && this.hasElementWithId(edgeData.target);
          var edgeConnectsThisAndOther = thisToOther || otherToThis;
          if (!edgeConnectsThisAndOther) {
            continue;
          }
          if (p.thisIsSrc || p.thisIsTgt) {
            if (p.thisIsSrc && !thisToOther) {
              continue;
            }
            if (p.thisIsTgt && !otherToThis) {
              continue;
            }
          }
          elements.push(edge);
        }
      }
      return this.spawn(elements, true);
    };
  }
  extend(elesfn$2, {
    connectedEdges: cache(function (selector) {
      var retEles = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var node = eles[i];
        if (!node.isNode()) {
          continue;
        }
        var edges = node._private.edges;
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          retEles.push(edge);
        }
      }
      return this.spawn(retEles, true).filter(selector);
    }, 'connectedEdges'),
    connectedNodes: cache(function (selector) {
      var retEles = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var edge = eles[i];
        if (!edge.isEdge()) {
          continue;
        }
        retEles.push(edge.source()[0]);
        retEles.push(edge.target()[0]);
      }
      return this.spawn(retEles, true).filter(selector);
    }, 'connectedNodes'),
    parallelEdges: cache(defineParallelEdgesFunction(), 'parallelEdges'),
    codirectedEdges: cache(defineParallelEdgesFunction({
      codirected: true
    }), 'codirectedEdges')
  });
  function defineParallelEdgesFunction(params) {
    var defaults = {
      codirected: false
    };
    params = extend({}, defaults, params);
    return function parallelEdgesImpl(selector) {
      // micro-optimised for renderer
      var elements = [];
      var edges = this.edges();
      var p = params;

      // look at all the edges in the collection
      for (var i = 0; i < edges.length; i++) {
        var edge1 = edges[i];
        var edge1_p = edge1._private;
        var src1 = edge1_p.source;
        var srcid1 = src1._private.data.id;
        var tgtid1 = edge1_p.data.target;
        var srcEdges1 = src1._private.edges;

        // look at edges connected to the src node of this edge
        for (var j = 0; j < srcEdges1.length; j++) {
          var edge2 = srcEdges1[j];
          var edge2data = edge2._private.data;
          var tgtid2 = edge2data.target;
          var srcid2 = edge2data.source;
          var codirected = tgtid2 === tgtid1 && srcid2 === srcid1;
          var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2;
          if (p.codirected && codirected || !p.codirected && (codirected || oppdirected)) {
            elements.push(edge2);
          }
        }
      }
      return this.spawn(elements, true).filter(selector);
    };
  }

  // Misc functions
  /////////////////

  extend(elesfn$2, {
    components: function components(root) {
      var self = this;
      var cy = self.cy();
      var visited = cy.collection();
      var unvisited = root == null ? self.nodes() : root.nodes();
      var components = [];
      if (root != null && unvisited.empty()) {
        // root may contain only edges
        unvisited = root.sources(); // doesn't matter which node to use (undirected), so just use the source sides
      }

      var visitInComponent = function visitInComponent(node, component) {
        visited.merge(node);
        unvisited.unmerge(node);
        component.merge(node);
      };
      if (unvisited.empty()) {
        return self.spawn();
      }
      var _loop = function _loop() {
        // each iteration yields a component
        var cmpt = cy.collection();
        components.push(cmpt);
        var root = unvisited[0];
        visitInComponent(root, cmpt);
        self.bfs({
          directed: false,
          roots: root,
          visit: function visit(v) {
            return visitInComponent(v, cmpt);
          }
        });
        cmpt.forEach(function (node) {
          node.connectedEdges().forEach(function (e) {
            // connectedEdges() usually cached
            if (self.has(e) && cmpt.has(e.source()) && cmpt.has(e.target())) {
              // has() is cheap
              cmpt.merge(e); // forEach() only considers nodes -- sets N at call time
            }
          });
        });
      };
      do {
        _loop();
      } while (unvisited.length > 0);
      return components;
    },
    component: function component() {
      var ele = this[0];
      return ele.cy().mutableElements().components(ele)[0];
    }
  });
  elesfn$2.componentsOf = elesfn$2.components;

  // represents a set of nodes, edges, or both together
  var Collection = function Collection(cy, elements) {
    var unique = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
    var removed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    if (cy === undefined) {
      error('A collection must have a reference to the core');
      return;
    }
    var map = new Map$2();
    var createdElements = false;
    if (!elements) {
      elements = [];
    } else if (elements.length > 0 && plainObject(elements[0]) && !element(elements[0])) {
      createdElements = true;

      // make elements from json and restore all at once later
      var eles = [];
      var elesIds = new Set$1();
      for (var i = 0, l = elements.length; i < l; i++) {
        var json = elements[i];
        if (json.data == null) {
          json.data = {};
        }
        var _data = json.data;

        // make sure newly created elements have valid ids
        if (_data.id == null) {
          _data.id = uuid();
        } else if (cy.hasElementWithId(_data.id) || elesIds.has(_data.id)) {
          continue; // can't create element if prior id already exists
        }

        var ele = new Element(cy, json, false);
        eles.push(ele);
        elesIds.add(_data.id);
      }
      elements = eles;
    }
    this.length = 0;
    for (var _i = 0, _l = elements.length; _i < _l; _i++) {
      var element$1 = elements[_i][0]; // [0] in case elements is an array of collections, rather than array of elements
      if (element$1 == null) {
        continue;
      }
      var id = element$1._private.data.id;
      if (!unique || !map.has(id)) {
        if (unique) {
          map.set(id, {
            index: this.length,
            ele: element$1
          });
        }
        this[this.length] = element$1;
        this.length++;
      }
    }
    this._private = {
      eles: this,
      cy: cy,
      get map() {
        if (this.lazyMap == null) {
          this.rebuildMap();
        }
        return this.lazyMap;
      },
      set map(m) {
        this.lazyMap = m;
      },
      rebuildMap: function rebuildMap() {
        var m = this.lazyMap = new Map$2();
        var eles = this.eles;
        for (var _i2 = 0; _i2 < eles.length; _i2++) {
          var _ele = eles[_i2];
          m.set(_ele.id(), {
            index: _i2,
            ele: _ele
          });
        }
      }
    };
    if (unique) {
      this._private.map = map;
    }

    // restore the elements if we created them from json
    if (createdElements && !removed) {
      this.restore();
    }
  };

  // Functions
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  // keep the prototypes in sync (an element has the same functions as a collection)
  // and use elefn and elesfn as shorthands to the prototypes
  var elesfn$1 = Element.prototype = Collection.prototype = Object.create(Array.prototype);
  elesfn$1.instanceString = function () {
    return 'collection';
  };
  elesfn$1.spawn = function (eles, unique) {
    return new Collection(this.cy(), eles, unique);
  };
  elesfn$1.spawnSelf = function () {
    return this.spawn(this);
  };
  elesfn$1.cy = function () {
    return this._private.cy;
  };
  elesfn$1.renderer = function () {
    return this._private.cy.renderer();
  };
  elesfn$1.element = function () {
    return this[0];
  };
  elesfn$1.collection = function () {
    if (collection(this)) {
      return this;
    } else {
      // an element
      return new Collection(this._private.cy, [this]);
    }
  };
  elesfn$1.unique = function () {
    return new Collection(this._private.cy, this, true);
  };
  elesfn$1.hasElementWithId = function (id) {
    id = '' + id; // id must be string

    return this._private.map.has(id);
  };
  elesfn$1.getElementById = function (id) {
    id = '' + id; // id must be string

    var cy = this._private.cy;
    var entry = this._private.map.get(id);
    return entry ? entry.ele : new Collection(cy); // get ele or empty collection
  };

  elesfn$1.$id = elesfn$1.getElementById;
  elesfn$1.poolIndex = function () {
    var cy = this._private.cy;
    var eles = cy._private.elements;
    var id = this[0]._private.data.id;
    return eles._private.map.get(id).index;
  };
  elesfn$1.indexOf = function (ele) {
    var id = ele[0]._private.data.id;
    return this._private.map.get(id).index;
  };
  elesfn$1.indexOfId = function (id) {
    id = '' + id; // id must be string

    return this._private.map.get(id).index;
  };
  elesfn$1.json = function (obj) {
    var ele = this.element();
    var cy = this.cy();
    if (ele == null && obj) {
      return this;
    } // can't set to no eles

    if (ele == null) {
      return undefined;
    } // can't get from no eles

    var p = ele._private;
    if (plainObject(obj)) {
      // set

      cy.startBatch();
      if (obj.data) {
        ele.data(obj.data);
        var _data2 = p.data;
        if (ele.isEdge()) {
          // source and target are immutable via data()
          var move = false;
          var spec = {};
          var src = obj.data.source;
          var tgt = obj.data.target;
          if (src != null && src != _data2.source) {
            spec.source = '' + src; // id must be string
            move = true;
          }
          if (tgt != null && tgt != _data2.target) {
            spec.target = '' + tgt; // id must be string
            move = true;
          }
          if (move) {
            ele = ele.move(spec);
          }
        } else {
          // parent is immutable via data()
          var newParentValSpecd = ('parent' in obj.data);
          var parent = obj.data.parent;
          if (newParentValSpecd && (parent != null || _data2.parent != null) && parent != _data2.parent) {
            if (parent === undefined) {
              // can't set undefined imperatively, so use null
              parent = null;
            }
            if (parent != null) {
              parent = '' + parent; // id must be string
            }

            ele = ele.move({
              parent: parent
            });
          }
        }
      }
      if (obj.position) {
        ele.position(obj.position);
      }

      // ignore group -- immutable

      var checkSwitch = function checkSwitch(k, trueFnName, falseFnName) {
        var obj_k = obj[k];
        if (obj_k != null && obj_k !== p[k]) {
          if (obj_k) {
            ele[trueFnName]();
          } else {
            ele[falseFnName]();
          }
        }
      };
      checkSwitch('removed', 'remove', 'restore');
      checkSwitch('selected', 'select', 'unselect');
      checkSwitch('selectable', 'selectify', 'unselectify');
      checkSwitch('locked', 'lock', 'unlock');
      checkSwitch('grabbable', 'grabify', 'ungrabify');
      checkSwitch('pannable', 'panify', 'unpanify');
      if (obj.classes != null) {
        ele.classes(obj.classes);
      }
      cy.endBatch();
      return this;
    } else if (obj === undefined) {
      // get

      var json = {
        data: copy(p.data),
        position: copy(p.position),
        group: p.group,
        removed: p.removed,
        selected: p.selected,
        selectable: p.selectable,
        locked: p.locked,
        grabbable: p.grabbable,
        pannable: p.pannable,
        classes: null
      };
      json.classes = '';
      var i = 0;
      p.classes.forEach(function (cls) {
        return json.classes += i++ === 0 ? cls : ' ' + cls;
      });
      return json;
    }
  };
  elesfn$1.jsons = function () {
    var jsons = [];
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var json = ele.json();
      jsons.push(json);
    }
    return jsons;
  };
  elesfn$1.clone = function () {
    var cy = this.cy();
    var elesArr = [];
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var json = ele.json();
      var clone = new Element(cy, json, false); // NB no restore

      elesArr.push(clone);
    }
    return new Collection(cy, elesArr);
  };
  elesfn$1.copy = elesfn$1.clone;
  elesfn$1.restore = function () {
    var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
    var addToPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var self = this;
    var cy = self.cy();
    var cy_p = cy._private;

    // create arrays of nodes and edges, since we need to
    // restore the nodes first
    var nodes = [];
    var edges = [];
    var elements;
    for (var _i3 = 0, l = self.length; _i3 < l; _i3++) {
      var ele = self[_i3];
      if (addToPool && !ele.removed()) {
        // don't need to handle this ele
        continue;
      }

      // keep nodes first in the array and edges after
      if (ele.isNode()) {
        // put to front of array if node
        nodes.push(ele);
      } else {
        // put to end of array if edge
        edges.push(ele);
      }
    }
    elements = nodes.concat(edges);
    var i;
    var removeFromElements = function removeFromElements() {
      elements.splice(i, 1);
      i--;
    };

    // now, restore each element
    for (i = 0; i < elements.length; i++) {
      var _ele2 = elements[i];
      var _private = _ele2._private;
      var _data3 = _private.data;

      // the traversal cache should start fresh when ele is added
      _ele2.clearTraversalCache();

      // set id and validate
      if (!addToPool && !_private.removed) ; else if (_data3.id === undefined) {
        _data3.id = uuid();
      } else if (number$1(_data3.id)) {
        _data3.id = '' + _data3.id; // now it's a string
      } else if (emptyString(_data3.id) || !string(_data3.id)) {
        error('Can not create element with invalid string ID `' + _data3.id + '`');

        // can't create element if it has empty string as id or non-string id
        removeFromElements();
        continue;
      } else if (cy.hasElementWithId(_data3.id)) {
        error('Can not create second element with ID `' + _data3.id + '`');

        // can't create element if one already has that id
        removeFromElements();
        continue;
      }
      var id = _data3.id; // id is finalised, now let's keep a ref

      if (_ele2.isNode()) {
        // extra checks for nodes
        var pos = _private.position;

        // make sure the nodes have a defined position

        if (pos.x == null) {
          pos.x = 0;
        }
        if (pos.y == null) {
          pos.y = 0;
        }
      }
      if (_ele2.isEdge()) {
        // extra checks for edges

        var edge = _ele2;
        var fields = ['source', 'target'];
        var fieldsLength = fields.length;
        var badSourceOrTarget = false;
        for (var j = 0; j < fieldsLength; j++) {
          var field = fields[j];
          var val = _data3[field];
          if (number$1(val)) {
            val = _data3[field] = '' + _data3[field]; // now string
          }

          if (val == null || val === '') {
            // can't create if source or target is not defined properly
            error('Can not create edge `' + id + '` with unspecified ' + field);
            badSourceOrTarget = true;
          } else if (!cy.hasElementWithId(val)) {
            // can't create edge if one of its nodes doesn't exist
            error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`');
            badSourceOrTarget = true;
          }
        }
        if (badSourceOrTarget) {
          removeFromElements();
          continue;
        } // can't create this

        var src = cy.getElementById(_data3.source);
        var tgt = cy.getElementById(_data3.target);

        // only one edge in node if loop
        if (src.same(tgt)) {
          src._private.edges.push(edge);
        } else {
          src._private.edges.push(edge);
          tgt._private.edges.push(edge);
        }
        edge._private.source = src;
        edge._private.target = tgt;
      } // if is edge

      // create mock ids / indexes maps for element so it can be used like collections
      _private.map = new Map$2();
      _private.map.set(id, {
        ele: _ele2,
        index: 0
      });
      _private.removed = false;
      if (addToPool) {
        cy.addToPool(_ele2);
      }
    } // for each element

    // do compound node sanity checks
    for (var _i4 = 0; _i4 < nodes.length; _i4++) {
      // each node
      var node = nodes[_i4];
      var _data4 = node._private.data;
      if (number$1(_data4.parent)) {
        // then automake string
        _data4.parent = '' + _data4.parent;
      }
      var parentId = _data4.parent;
      var specifiedParent = parentId != null;
      if (specifiedParent || node._private.parent) {
        var parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById(parentId);
        if (parent.empty()) {
          // non-existant parent; just remove it
          _data4.parent = undefined;
        } else if (parent[0].removed()) {
          warn('Node added with missing parent, reference to parent removed');
          _data4.parent = undefined;
          node._private.parent = null;
        } else {
          var selfAsParent = false;
          var ancestor = parent;
          while (!ancestor.empty()) {
            if (node.same(ancestor)) {
              // mark self as parent and remove from data
              selfAsParent = true;
              _data4.parent = undefined; // remove parent reference

              // exit or we loop forever
              break;
            }
            ancestor = ancestor.parent();
          }
          if (!selfAsParent) {
            // connect with children
            parent[0]._private.children.push(node);
            node._private.parent = parent[0];

            // let the core know we have a compound graph
            cy_p.hasCompoundNodes = true;
          }
        } // else
      } // if specified parent
    } // for each node

    if (elements.length > 0) {
      var restored = elements.length === self.length ? self : new Collection(cy, elements);
      for (var _i5 = 0; _i5 < restored.length; _i5++) {
        var _ele3 = restored[_i5];
        if (_ele3.isNode()) {
          continue;
        }

        // adding an edge invalidates the traversal caches for the parallel edges
        _ele3.parallelEdges().clearTraversalCache();

        // adding an edge invalidates the traversal cache for the connected nodes
        _ele3.source().clearTraversalCache();
        _ele3.target().clearTraversalCache();
      }
      var toUpdateStyle;
      if (cy_p.hasCompoundNodes) {
        toUpdateStyle = cy.collection().merge(restored).merge(restored.connectedNodes()).merge(restored.parent());
      } else {
        toUpdateStyle = restored;
      }
      toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(notifyRenderer);
      if (notifyRenderer) {
        restored.emitAndNotify('add');
      } else if (addToPool) {
        restored.emit('add');
      }
    }
    return self; // chainability
  };

  elesfn$1.removed = function () {
    var ele = this[0];
    return ele && ele._private.removed;
  };
  elesfn$1.inside = function () {
    var ele = this[0];
    return ele && !ele._private.removed;
  };
  elesfn$1.remove = function () {
    var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
    var removeFromPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var self = this;
    var elesToRemove = [];
    var elesToRemoveIds = {};
    var cy = self._private.cy;

    // add connected edges
    function addConnectedEdges(node) {
      var edges = node._private.edges;
      for (var i = 0; i < edges.length; i++) {
        add(edges[i]);
      }
    }

    // add descendant nodes
    function addChildren(node) {
      var children = node._private.children;
      for (var i = 0; i < children.length; i++) {
        add(children[i]);
      }
    }
    function add(ele) {
      var alreadyAdded = elesToRemoveIds[ele.id()];
      if (removeFromPool && ele.removed() || alreadyAdded) {
        return;
      } else {
        elesToRemoveIds[ele.id()] = true;
      }
      if (ele.isNode()) {
        elesToRemove.push(ele); // nodes are removed last

        addConnectedEdges(ele);
        addChildren(ele);
      } else {
        elesToRemove.unshift(ele); // edges are removed first
      }
    }

    // make the list of elements to remove
    // (may be removing more than specified due to connected edges etc)

    for (var i = 0, l = self.length; i < l; i++) {
      var ele = self[i];
      add(ele);
    }
    function removeEdgeRef(node, edge) {
      var connectedEdges = node._private.edges;
      removeFromArray(connectedEdges, edge);

      // removing an edges invalidates the traversal cache for its nodes
      node.clearTraversalCache();
    }
    function removeParallelRef(pllEdge) {
      // removing an edge invalidates the traversal caches for the parallel edges
      pllEdge.clearTraversalCache();
    }
    var alteredParents = [];
    alteredParents.ids = {};
    function removeChildRef(parent, ele) {
      ele = ele[0];
      parent = parent[0];
      var children = parent._private.children;
      var pid = parent.id();
      removeFromArray(children, ele); // remove parent => child ref

      ele._private.parent = null; // remove child => parent ref

      if (!alteredParents.ids[pid]) {
        alteredParents.ids[pid] = true;
        alteredParents.push(parent);
      }
    }
    self.dirtyCompoundBoundsCache();
    if (removeFromPool) {
      cy.removeFromPool(elesToRemove); // remove from core pool
    }

    for (var _i6 = 0; _i6 < elesToRemove.length; _i6++) {
      var _ele4 = elesToRemove[_i6];
      if (_ele4.isEdge()) {
        // remove references to this edge in its connected nodes
        var src = _ele4.source()[0];
        var tgt = _ele4.target()[0];
        removeEdgeRef(src, _ele4);
        removeEdgeRef(tgt, _ele4);
        var pllEdges = _ele4.parallelEdges();
        for (var j = 0; j < pllEdges.length; j++) {
          var pllEdge = pllEdges[j];
          removeParallelRef(pllEdge);
          if (pllEdge.isBundledBezier()) {
            pllEdge.dirtyBoundingBoxCache();
          }
        }
      } else {
        // remove reference to parent
        var parent = _ele4.parent();
        if (parent.length !== 0) {
          removeChildRef(parent, _ele4);
        }
      }
      if (removeFromPool) {
        // mark as removed
        _ele4._private.removed = true;
      }
    }

    // check to see if we have a compound graph or not
    var elesStillInside = cy._private.elements;
    cy._private.hasCompoundNodes = false;
    for (var _i7 = 0; _i7 < elesStillInside.length; _i7++) {
      var _ele5 = elesStillInside[_i7];
      if (_ele5.isParent()) {
        cy._private.hasCompoundNodes = true;
        break;
      }
    }
    var removedElements = new Collection(this.cy(), elesToRemove);
    if (removedElements.size() > 0) {
      // must manually notify since trigger won't do this automatically once removed

      if (notifyRenderer) {
        removedElements.emitAndNotify('remove');
      } else if (removeFromPool) {
        removedElements.emit('remove');
      }
    }

    // the parents who were modified by the removal need their style updated
    for (var _i8 = 0; _i8 < alteredParents.length; _i8++) {
      var _ele6 = alteredParents[_i8];
      if (!removeFromPool || !_ele6.removed()) {
        _ele6.updateStyle();
      }
    }
    return removedElements;
  };
  elesfn$1.move = function (struct) {
    var cy = this._private.cy;
    var eles = this;

    // just clean up refs, caches, etc. in the same way as when removing and then restoring
    // (our calls to remove/restore do not remove from the graph or make events)
    var notifyRenderer = false;
    var modifyPool = false;
    var toString = function toString(id) {
      return id == null ? id : '' + id;
    }; // id must be string

    if (struct.source !== undefined || struct.target !== undefined) {
      var srcId = toString(struct.source);
      var tgtId = toString(struct.target);
      var srcExists = srcId != null && cy.hasElementWithId(srcId);
      var tgtExists = tgtId != null && cy.hasElementWithId(tgtId);
      if (srcExists || tgtExists) {
        cy.batch(function () {
          // avoid duplicate style updates
          eles.remove(notifyRenderer, modifyPool); // clean up refs etc.
          eles.emitAndNotify('moveout');
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            var _data5 = ele._private.data;
            if (ele.isEdge()) {
              if (srcExists) {
                _data5.source = srcId;
              }
              if (tgtExists) {
                _data5.target = tgtId;
              }
            }
          }
          eles.restore(notifyRenderer, modifyPool); // make new refs, style, etc.
        });

        eles.emitAndNotify('move');
      }
    } else if (struct.parent !== undefined) {
      // move node to new parent
      var parentId = toString(struct.parent);
      var parentExists = parentId === null || cy.hasElementWithId(parentId);
      if (parentExists) {
        var pidToAssign = parentId === null ? undefined : parentId;
        cy.batch(function () {
          // avoid duplicate style updates
          var updated = eles.remove(notifyRenderer, modifyPool); // clean up refs etc.
          updated.emitAndNotify('moveout');
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            var _data6 = ele._private.data;
            if (ele.isNode()) {
              _data6.parent = pidToAssign;
            }
          }
          updated.restore(notifyRenderer, modifyPool); // make new refs, style, etc.
        });

        eles.emitAndNotify('move');
      }
    }
    return this;
  };
  [elesfn$j, elesfn$i, elesfn$h, elesfn$g, elesfn$f, data, elesfn$d, dimensions, elesfn$9, elesfn$8, elesfn$7, elesfn$6, elesfn$5, elesfn$4, elesfn$3, elesfn$2].forEach(function (props) {
    extend(elesfn$1, props);
  });

  var corefn$9 = {
    add: function add(opts) {
      var elements;
      var cy = this;

      // add the elements
      if (elementOrCollection(opts)) {
        var eles = opts;
        if (eles._private.cy === cy) {
          // same instance => just restore
          elements = eles.restore();
        } else {
          // otherwise, copy from json
          var jsons = [];
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            jsons.push(ele.json());
          }
          elements = new Collection(cy, jsons);
        }
      }

      // specify an array of options
      else if (array(opts)) {
        var _jsons = opts;
        elements = new Collection(cy, _jsons);
      }

      // specify via opts.nodes and opts.edges
      else if (plainObject(opts) && (array(opts.nodes) || array(opts.edges))) {
        var elesByGroup = opts;
        var _jsons2 = [];
        var grs = ['nodes', 'edges'];
        for (var _i = 0, il = grs.length; _i < il; _i++) {
          var group = grs[_i];
          var elesArray = elesByGroup[group];
          if (array(elesArray)) {
            for (var j = 0, jl = elesArray.length; j < jl; j++) {
              var json = extend({
                group: group
              }, elesArray[j]);
              _jsons2.push(json);
            }
          }
        }
        elements = new Collection(cy, _jsons2);
      }

      // specify options for one element
      else {
        var _json = opts;
        elements = new Element(cy, _json).collection();
      }
      return elements;
    },
    remove: function remove(collection) {
      if (elementOrCollection(collection)) ; else if (string(collection)) {
        var selector = collection;
        collection = this.$(selector);
      }
      return collection.remove();
    }
  };

  /* global Float32Array */

  /*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
  function generateCubicBezier(mX1, mY1, mX2, mY2) {
    var NEWTON_ITERATIONS = 4,
      NEWTON_MIN_SLOPE = 0.001,
      SUBDIVISION_PRECISION = 0.0000001,
      SUBDIVISION_MAX_ITERATIONS = 10,
      kSplineTableSize = 11,
      kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
      float32ArraySupported = typeof Float32Array !== 'undefined';

    /* Must contain four arguments. */
    if (arguments.length !== 4) {
      return false;
    }

    /* Arguments must be numbers. */
    for (var i = 0; i < 4; ++i) {
      if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
        return false;
      }
    }

    /* X values must be in the [0, 1] range. */
    mX1 = Math.min(mX1, 1);
    mX2 = Math.min(mX2, 1);
    mX1 = Math.max(mX1, 0);
    mX2 = Math.max(mX2, 0);
    var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
    function A(aA1, aA2) {
      return 1.0 - 3.0 * aA2 + 3.0 * aA1;
    }
    function B(aA1, aA2) {
      return 3.0 * aA2 - 6.0 * aA1;
    }
    function C(aA1) {
      return 3.0 * aA1;
    }
    function calcBezier(aT, aA1, aA2) {
      return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
    }
    function getSlope(aT, aA1, aA2) {
      return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
    }
    function newtonRaphsonIterate(aX, aGuessT) {
      for (var _i = 0; _i < NEWTON_ITERATIONS; ++_i) {
        var currentSlope = getSlope(aGuessT, mX1, mX2);
        if (currentSlope === 0.0) {
          return aGuessT;
        }
        var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
        aGuessT -= currentX / currentSlope;
      }
      return aGuessT;
    }
    function calcSampleValues() {
      for (var _i2 = 0; _i2 < kSplineTableSize; ++_i2) {
        mSampleValues[_i2] = calcBezier(_i2 * kSampleStepSize, mX1, mX2);
      }
    }
    function binarySubdivide(aX, aA, aB) {
      var currentX,
        currentT,
        i = 0;
      do {
        currentT = aA + (aB - aA) / 2.0;
        currentX = calcBezier(currentT, mX1, mX2) - aX;
        if (currentX > 0.0) {
          aB = currentT;
        } else {
          aA = currentT;
        }
      } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
      return currentT;
    }
    function getTForX(aX) {
      var intervalStart = 0.0,
        currentSample = 1,
        lastSample = kSplineTableSize - 1;
      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
        intervalStart += kSampleStepSize;
      }
      --currentSample;
      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]),
        guessForT = intervalStart + dist * kSampleStepSize,
        initialSlope = getSlope(guessForT, mX1, mX2);
      if (initialSlope >= NEWTON_MIN_SLOPE) {
        return newtonRaphsonIterate(aX, guessForT);
      } else if (initialSlope === 0.0) {
        return guessForT;
      } else {
        return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
      }
    }
    var _precomputed = false;
    function precompute() {
      _precomputed = true;
      if (mX1 !== mY1 || mX2 !== mY2) {
        calcSampleValues();
      }
    }
    var f = function f(aX) {
      if (!_precomputed) {
        precompute();
      }
      if (mX1 === mY1 && mX2 === mY2) {
        return aX;
      }
      if (aX === 0) {
        return 0;
      }
      if (aX === 1) {
        return 1;
      }
      return calcBezier(getTForX(aX), mY1, mY2);
    };
    f.getControlPoints = function () {
      return [{
        x: mX1,
        y: mY1
      }, {
        x: mX2,
        y: mY2
      }];
    };
    var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
    f.toString = function () {
      return str;
    };
    return f;
  }

  /*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
  /* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass
     then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */
  var generateSpringRK4 = function () {
    function springAccelerationForState(state) {
      return -state.tension * state.x - state.friction * state.v;
    }
    function springEvaluateStateWithDerivative(initialState, dt, derivative) {
      var state = {
        x: initialState.x + derivative.dx * dt,
        v: initialState.v + derivative.dv * dt,
        tension: initialState.tension,
        friction: initialState.friction
      };
      return {
        dx: state.v,
        dv: springAccelerationForState(state)
      };
    }
    function springIntegrateState(state, dt) {
      var a = {
          dx: state.v,
          dv: springAccelerationForState(state)
        },
        b = springEvaluateStateWithDerivative(state, dt * 0.5, a),
        c = springEvaluateStateWithDerivative(state, dt * 0.5, b),
        d = springEvaluateStateWithDerivative(state, dt, c),
        dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),
        dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
      state.x = state.x + dxdt * dt;
      state.v = state.v + dvdt * dt;
      return state;
    }
    return function springRK4Factory(tension, friction, duration) {
      var initState = {
          x: -1,
          v: 0,
          tension: null,
          friction: null
        },
        path = [0],
        time_lapsed = 0,
        tolerance = 1 / 10000,
        DT = 16 / 1000,
        have_duration,
        dt,
        last_state;
      tension = parseFloat(tension) || 500;
      friction = parseFloat(friction) || 20;
      duration = duration || null;
      initState.tension = tension;
      initState.friction = friction;
      have_duration = duration !== null;

      /* Calculate the actual time it takes for this animation to complete with the provided conditions. */
      if (have_duration) {
        /* Run the simulation without a duration. */
        time_lapsed = springRK4Factory(tension, friction);
        /* Compute the adjusted time delta. */
        dt = time_lapsed / duration * DT;
      } else {
        dt = DT;
      }
      for (;;) {
        /* Next/step function .*/
        last_state = springIntegrateState(last_state || initState, dt);
        /* Store the position. */
        path.push(1 + last_state.x);
        time_lapsed += 16;
        /* If the change threshold is reached, break. */
        if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {
          break;
        }
      }

      /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the
         computed path and returns a snapshot of the position according to a given percentComplete. */
      return !have_duration ? time_lapsed : function (percentComplete) {
        return path[percentComplete * (path.length - 1) | 0];
      };
    };
  }();

  var cubicBezier = function cubicBezier(t1, p1, t2, p2) {
    var bezier = generateCubicBezier(t1, p1, t2, p2);
    return function (start, end, percent) {
      return start + (end - start) * bezier(percent);
    };
  };
  var easings = {
    'linear': function linear(start, end, percent) {
      return start + (end - start) * percent;
    },
    // default easings
    'ease': cubicBezier(0.25, 0.1, 0.25, 1),
    'ease-in': cubicBezier(0.42, 0, 1, 1),
    'ease-out': cubicBezier(0, 0, 0.58, 1),
    'ease-in-out': cubicBezier(0.42, 0, 0.58, 1),
    // sine
    'ease-in-sine': cubicBezier(0.47, 0, 0.745, 0.715),
    'ease-out-sine': cubicBezier(0.39, 0.575, 0.565, 1),
    'ease-in-out-sine': cubicBezier(0.445, 0.05, 0.55, 0.95),
    // quad
    'ease-in-quad': cubicBezier(0.55, 0.085, 0.68, 0.53),
    'ease-out-quad': cubicBezier(0.25, 0.46, 0.45, 0.94),
    'ease-in-out-quad': cubicBezier(0.455, 0.03, 0.515, 0.955),
    // cubic
    'ease-in-cubic': cubicBezier(0.55, 0.055, 0.675, 0.19),
    'ease-out-cubic': cubicBezier(0.215, 0.61, 0.355, 1),
    'ease-in-out-cubic': cubicBezier(0.645, 0.045, 0.355, 1),
    // quart
    'ease-in-quart': cubicBezier(0.895, 0.03, 0.685, 0.22),
    'ease-out-quart': cubicBezier(0.165, 0.84, 0.44, 1),
    'ease-in-out-quart': cubicBezier(0.77, 0, 0.175, 1),
    // quint
    'ease-in-quint': cubicBezier(0.755, 0.05, 0.855, 0.06),
    'ease-out-quint': cubicBezier(0.23, 1, 0.32, 1),
    'ease-in-out-quint': cubicBezier(0.86, 0, 0.07, 1),
    // expo
    'ease-in-expo': cubicBezier(0.95, 0.05, 0.795, 0.035),
    'ease-out-expo': cubicBezier(0.19, 1, 0.22, 1),
    'ease-in-out-expo': cubicBezier(1, 0, 0, 1),
    // circ
    'ease-in-circ': cubicBezier(0.6, 0.04, 0.98, 0.335),
    'ease-out-circ': cubicBezier(0.075, 0.82, 0.165, 1),
    'ease-in-out-circ': cubicBezier(0.785, 0.135, 0.15, 0.86),
    // user param easings...

    'spring': function spring(tension, friction, duration) {
      if (duration === 0) {
        // can't get a spring w/ duration 0
        return easings.linear; // duration 0 => jump to end so impl doesn't matter
      }

      var spring = generateSpringRK4(tension, friction, duration);
      return function (start, end, percent) {
        return start + (end - start) * spring(percent);
      };
    },
    'cubic-bezier': cubicBezier
  };

  function getEasedValue(type, start, end, percent, easingFn) {
    if (percent === 1) {
      return end;
    }
    if (start === end) {
      return end;
    }
    var val = easingFn(start, end, percent);
    if (type == null) {
      return val;
    }
    if (type.roundValue || type.color) {
      val = Math.round(val);
    }
    if (type.min !== undefined) {
      val = Math.max(val, type.min);
    }
    if (type.max !== undefined) {
      val = Math.min(val, type.max);
    }
    return val;
  }
  function getValue(prop, spec) {
    if (prop.pfValue != null || prop.value != null) {
      if (prop.pfValue != null && (spec == null || spec.type.units !== '%')) {
        return prop.pfValue;
      } else {
        return prop.value;
      }
    } else {
      return prop;
    }
  }
  function ease(startProp, endProp, percent, easingFn, propSpec) {
    var type = propSpec != null ? propSpec.type : null;
    if (percent < 0) {
      percent = 0;
    } else if (percent > 1) {
      percent = 1;
    }
    var start = getValue(startProp, propSpec);
    var end = getValue(endProp, propSpec);
    if (number$1(start) && number$1(end)) {
      return getEasedValue(type, start, end, percent, easingFn);
    } else if (array(start) && array(end)) {
      var easedArr = [];
      for (var i = 0; i < end.length; i++) {
        var si = start[i];
        var ei = end[i];
        if (si != null && ei != null) {
          var val = getEasedValue(type, si, ei, percent, easingFn);
          easedArr.push(val);
        } else {
          easedArr.push(ei);
        }
      }
      return easedArr;
    }
    return undefined;
  }

  function step$1(self, ani, now, isCore) {
    var isEles = !isCore;
    var _p = self._private;
    var ani_p = ani._private;
    var pEasing = ani_p.easing;
    var startTime = ani_p.startTime;
    var cy = isCore ? self : self.cy();
    var style = cy.style();
    if (!ani_p.easingImpl) {
      if (pEasing == null) {
        // use default
        ani_p.easingImpl = easings['linear'];
      } else {
        // then define w/ name
        var easingVals;
        if (string(pEasing)) {
          var easingProp = style.parse('transition-timing-function', pEasing);
          easingVals = easingProp.value;
        } else {
          // then assume preparsed array
          easingVals = pEasing;
        }
        var name, args;
        if (string(easingVals)) {
          name = easingVals;
          args = [];
        } else {
          name = easingVals[1];
          args = easingVals.slice(2).map(function (n) {
            return +n;
          });
        }
        if (args.length > 0) {
          // create with args
          if (name === 'spring') {
            args.push(ani_p.duration); // need duration to generate spring
          }

          ani_p.easingImpl = easings[name].apply(null, args);
        } else {
          // static impl by name
          ani_p.easingImpl = easings[name];
        }
      }
    }
    var easing = ani_p.easingImpl;
    var percent;
    if (ani_p.duration === 0) {
      percent = 1;
    } else {
      percent = (now - startTime) / ani_p.duration;
    }
    if (ani_p.applying) {
      percent = ani_p.progress;
    }
    if (percent < 0) {
      percent = 0;
    } else if (percent > 1) {
      percent = 1;
    }
    if (ani_p.delay == null) {
      // then update

      var startPos = ani_p.startPosition;
      var endPos = ani_p.position;
      if (endPos && isEles && !self.locked()) {
        var newPos = {};
        if (valid(startPos.x, endPos.x)) {
          newPos.x = ease(startPos.x, endPos.x, percent, easing);
        }
        if (valid(startPos.y, endPos.y)) {
          newPos.y = ease(startPos.y, endPos.y, percent, easing);
        }
        self.position(newPos);
      }
      var startPan = ani_p.startPan;
      var endPan = ani_p.pan;
      var pan = _p.pan;
      var animatingPan = endPan != null && isCore;
      if (animatingPan) {
        if (valid(startPan.x, endPan.x)) {
          pan.x = ease(startPan.x, endPan.x, percent, easing);
        }
        if (valid(startPan.y, endPan.y)) {
          pan.y = ease(startPan.y, endPan.y, percent, easing);
        }
        self.emit('pan');
      }
      var startZoom = ani_p.startZoom;
      var endZoom = ani_p.zoom;
      var animatingZoom = endZoom != null && isCore;
      if (animatingZoom) {
        if (valid(startZoom, endZoom)) {
          _p.zoom = bound(_p.minZoom, ease(startZoom, endZoom, percent, easing), _p.maxZoom);
        }
        self.emit('zoom');
      }
      if (animatingPan || animatingZoom) {
        self.emit('viewport');
      }
      var props = ani_p.style;
      if (props && props.length > 0 && isEles) {
        for (var i = 0; i < props.length; i++) {
          var prop = props[i];
          var _name = prop.name;
          var end = prop;
          var start = ani_p.startStyle[_name];
          var propSpec = style.properties[start.name];
          var easedVal = ease(start, end, percent, easing, propSpec);
          style.overrideBypass(self, _name, easedVal);
        } // for props

        self.emit('style');
      } // if
    }

    ani_p.progress = percent;
    return percent;
  }
  function valid(start, end) {
    if (start == null || end == null) {
      return false;
    }
    if (number$1(start) && number$1(end)) {
      return true;
    } else if (start && end) {
      return true;
    }
    return false;
  }

  function startAnimation(self, ani, now, isCore) {
    var ani_p = ani._private;
    ani_p.started = true;
    ani_p.startTime = now - ani_p.progress * ani_p.duration;
  }

  function stepAll(now, cy) {
    var eles = cy._private.aniEles;
    var doneEles = [];
    function stepOne(ele, isCore) {
      var _p = ele._private;
      var current = _p.animation.current;
      var queue = _p.animation.queue;
      var ranAnis = false;

      // if nothing currently animating, get something from the queue
      if (current.length === 0) {
        var next = queue.shift();
        if (next) {
          current.push(next);
        }
      }
      var callbacks = function callbacks(_callbacks) {
        for (var j = _callbacks.length - 1; j >= 0; j--) {
          var cb = _callbacks[j];
          cb();
        }
        _callbacks.splice(0, _callbacks.length);
      };

      // step and remove if done
      for (var i = current.length - 1; i >= 0; i--) {
        var ani = current[i];
        var ani_p = ani._private;
        if (ani_p.stopped) {
          current.splice(i, 1);
          ani_p.hooked = false;
          ani_p.playing = false;
          ani_p.started = false;
          callbacks(ani_p.frames);
          continue;
        }
        if (!ani_p.playing && !ani_p.applying) {
          continue;
        }

        // an apply() while playing shouldn't do anything
        if (ani_p.playing && ani_p.applying) {
          ani_p.applying = false;
        }
        if (!ani_p.started) {
          startAnimation(ele, ani, now);
        }
        step$1(ele, ani, now, isCore);
        if (ani_p.applying) {
          ani_p.applying = false;
        }
        callbacks(ani_p.frames);
        if (ani_p.step != null) {
          ani_p.step(now);
        }
        if (ani.completed()) {
          current.splice(i, 1);
          ani_p.hooked = false;
          ani_p.playing = false;
          ani_p.started = false;
          callbacks(ani_p.completes);
        }
        ranAnis = true;
      }
      if (!isCore && current.length === 0 && queue.length === 0) {
        doneEles.push(ele);
      }
      return ranAnis;
    } // stepElement

    // handle all eles
    var ranEleAni = false;
    for (var e = 0; e < eles.length; e++) {
      var ele = eles[e];
      var handledThisEle = stepOne(ele);
      ranEleAni = ranEleAni || handledThisEle;
    } // each element

    var ranCoreAni = stepOne(cy, true);

    // notify renderer
    if (ranEleAni || ranCoreAni) {
      if (eles.length > 0) {
        cy.notify('draw', eles);
      } else {
        cy.notify('draw');
      }
    }

    // remove elements from list of currently animating if its queues are empty
    eles.unmerge(doneEles);
    cy.emit('step');
  } // stepAll

  var corefn$8 = {
    // pull in animation functions
    animate: define.animate(),
    animation: define.animation(),
    animated: define.animated(),
    clearQueue: define.clearQueue(),
    delay: define.delay(),
    delayAnimation: define.delayAnimation(),
    stop: define.stop(),
    addToAnimationPool: function addToAnimationPool(eles) {
      var cy = this;
      if (!cy.styleEnabled()) {
        return;
      } // save cycles when no style used

      cy._private.aniEles.merge(eles);
    },
    stopAnimationLoop: function stopAnimationLoop() {
      this._private.animationsRunning = false;
    },
    startAnimationLoop: function startAnimationLoop() {
      var cy = this;
      cy._private.animationsRunning = true;
      if (!cy.styleEnabled()) {
        return;
      } // save cycles when no style used

      // NB the animation loop will exec in headless environments if style enabled
      // and explicit cy.destroy() is necessary to stop the loop

      function headlessStep() {
        if (!cy._private.animationsRunning) {
          return;
        }
        requestAnimationFrame(function animationStep(now) {
          stepAll(now, cy);
          headlessStep();
        });
      }
      var renderer = cy.renderer();
      if (renderer && renderer.beforeRender) {
        // let the renderer schedule animations
        renderer.beforeRender(function rendererAnimationStep(willDraw, now) {
          stepAll(now, cy);
        }, renderer.beforeRenderPriorities.animations);
      } else {
        // manage the animation loop ourselves
        headlessStep(); // first call
      }
    }
  };

  var emitterOptions = {
    qualifierCompare: function qualifierCompare(selector1, selector2) {
      if (selector1 == null || selector2 == null) {
        return selector1 == null && selector2 == null;
      } else {
        return selector1.sameText(selector2);
      }
    },
    eventMatches: function eventMatches(cy, listener, eventObj) {
      var selector = listener.qualifier;
      if (selector != null) {
        return cy !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);
      }
      return true;
    },
    addEventFields: function addEventFields(cy, evt) {
      evt.cy = cy;
      evt.target = cy;
    },
    callbackContext: function callbackContext(cy, listener, eventObj) {
      return listener.qualifier != null ? eventObj.target : cy;
    }
  };
  var argSelector = function argSelector(arg) {
    if (string(arg)) {
      return new Selector(arg);
    } else {
      return arg;
    }
  };
  var elesfn = {
    createEmitter: function createEmitter() {
      var _p = this._private;
      if (!_p.emitter) {
        _p.emitter = new Emitter(emitterOptions, this);
      }
      return this;
    },
    emitter: function emitter() {
      return this._private.emitter;
    },
    on: function on(events, selector, callback) {
      this.emitter().on(events, argSelector(selector), callback);
      return this;
    },
    removeListener: function removeListener(events, selector, callback) {
      this.emitter().removeListener(events, argSelector(selector), callback);
      return this;
    },
    removeAllListeners: function removeAllListeners() {
      this.emitter().removeAllListeners();
      return this;
    },
    one: function one(events, selector, callback) {
      this.emitter().one(events, argSelector(selector), callback);
      return this;
    },
    once: function once(events, selector, callback) {
      this.emitter().one(events, argSelector(selector), callback);
      return this;
    },
    emit: function emit(events, extraParams) {
      this.emitter().emit(events, extraParams);
      return this;
    },
    emitAndNotify: function emitAndNotify(event, eles) {
      this.emit(event);
      this.notify(event, eles);
      return this;
    }
  };
  define.eventAliasesOn(elesfn);

  var corefn$7 = {
    png: function png(options) {
      var renderer = this._private.renderer;
      options = options || {};
      return renderer.png(options);
    },
    jpg: function jpg(options) {
      var renderer = this._private.renderer;
      options = options || {};
      options.bg = options.bg || '#fff';
      return renderer.jpg(options);
    }
  };
  corefn$7.jpeg = corefn$7.jpg;

  var corefn$6 = {
    layout: function layout(options) {
      var cy = this;
      if (options == null) {
        error('Layout options must be specified to make a layout');
        return;
      }
      if (options.name == null) {
        error('A `name` must be specified to make a layout');
        return;
      }
      var name = options.name;
      var Layout = cy.extension('layout', name);
      if (Layout == null) {
        error('No such layout `' + name + '` found.  Did you forget to import it and `cytoscape.use()` it?');
        return;
      }
      var eles;
      if (string(options.eles)) {
        eles = cy.$(options.eles);
      } else {
        eles = options.eles != null ? options.eles : cy.$();
      }
      var layout = new Layout(extend({}, options, {
        cy: cy,
        eles: eles
      }));
      return layout;
    }
  };
  corefn$6.createLayout = corefn$6.makeLayout = corefn$6.layout;

  var corefn$5 = {
    notify: function notify(eventName, eventEles) {
      var _p = this._private;
      if (this.batching()) {
        _p.batchNotifications = _p.batchNotifications || {};
        var eles = _p.batchNotifications[eventName] = _p.batchNotifications[eventName] || this.collection();
        if (eventEles != null) {
          eles.merge(eventEles);
        }
        return; // notifications are disabled during batching
      }

      if (!_p.notificationsEnabled) {
        return;
      } // exit on disabled

      var renderer = this.renderer();

      // exit if destroy() called on core or renderer in between frames #1499 #1528
      if (this.destroyed() || !renderer) {
        return;
      }
      renderer.notify(eventName, eventEles);
    },
    notifications: function notifications(bool) {
      var p = this._private;
      if (bool === undefined) {
        return p.notificationsEnabled;
      } else {
        p.notificationsEnabled = bool ? true : false;
      }
      return this;
    },
    noNotifications: function noNotifications(callback) {
      this.notifications(false);
      callback();
      this.notifications(true);
    },
    batching: function batching() {
      return this._private.batchCount > 0;
    },
    startBatch: function startBatch() {
      var _p = this._private;
      if (_p.batchCount == null) {
        _p.batchCount = 0;
      }
      if (_p.batchCount === 0) {
        _p.batchStyleEles = this.collection();
        _p.batchNotifications = {};
      }
      _p.batchCount++;
      return this;
    },
    endBatch: function endBatch() {
      var _p = this._private;
      if (_p.batchCount === 0) {
        return this;
      }
      _p.batchCount--;
      if (_p.batchCount === 0) {
        // update style for dirty eles
        _p.batchStyleEles.updateStyle();
        var renderer = this.renderer();

        // notify the renderer of queued eles and event types
        Object.keys(_p.batchNotifications).forEach(function (eventName) {
          var eles = _p.batchNotifications[eventName];
          if (eles.empty()) {
            renderer.notify(eventName);
          } else {
            renderer.notify(eventName, eles);
          }
        });
      }
      return this;
    },
    batch: function batch(callback) {
      this.startBatch();
      callback();
      this.endBatch();
      return this;
    },
    // for backwards compatibility
    batchData: function batchData(map) {
      var cy = this;
      return this.batch(function () {
        var ids = Object.keys(map);
        for (var i = 0; i < ids.length; i++) {
          var id = ids[i];
          var data = map[id];
          var ele = cy.getElementById(id);
          ele.data(data);
        }
      });
    }
  };

  var rendererDefaults = defaults$g({
    hideEdgesOnViewport: false,
    textureOnViewport: false,
    motionBlur: false,
    motionBlurOpacity: 0.05,
    pixelRatio: undefined,
    desktopTapThreshold: 4,
    touchTapThreshold: 8,
    wheelSensitivity: 1,
    debug: false,
    showFps: false
  });
  var corefn$4 = {
    renderTo: function renderTo(context, zoom, pan, pxRatio) {
      var r = this._private.renderer;
      r.renderTo(context, zoom, pan, pxRatio);
      return this;
    },
    renderer: function renderer() {
      return this._private.renderer;
    },
    forceRender: function forceRender() {
      this.notify('draw');
      return this;
    },
    resize: function resize() {
      this.invalidateSize();
      this.emitAndNotify('resize');
      return this;
    },
    initRenderer: function initRenderer(options) {
      var cy = this;
      var RendererProto = cy.extension('renderer', options.name);
      if (RendererProto == null) {
        error("Can not initialise: No such renderer `".concat(options.name, "` found. Did you forget to import it and `cytoscape.use()` it?"));
        return;
      }
      if (options.wheelSensitivity !== undefined) {
        warn("You have set a custom wheel sensitivity.  This will make your app zoom unnaturally when using mainstream mice.  You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");
      }
      var rOpts = rendererDefaults(options);
      rOpts.cy = cy;
      cy._private.renderer = new RendererProto(rOpts);
      this.notify('init');
    },
    destroyRenderer: function destroyRenderer() {
      var cy = this;
      cy.notify('destroy'); // destroy the renderer

      var domEle = cy.container();
      if (domEle) {
        domEle._cyreg = null;
        while (domEle.childNodes.length > 0) {
          domEle.removeChild(domEle.childNodes[0]);
        }
      }
      cy._private.renderer = null; // to be extra safe, remove the ref
      cy.mutableElements().forEach(function (ele) {
        var _p = ele._private;
        _p.rscratch = {};
        _p.rstyle = {};
        _p.animation.current = [];
        _p.animation.queue = [];
      });
    },
    onRender: function onRender(fn) {
      return this.on('render', fn);
    },
    offRender: function offRender(fn) {
      return this.off('render', fn);
    }
  };
  corefn$4.invalidateDimensions = corefn$4.resize;

  var corefn$3 = {
    // get a collection
    // - empty collection on no args
    // - collection of elements in the graph on selector arg
    // - guarantee a returned collection when elements or collection specified
    collection: function collection(eles, opts) {
      if (string(eles)) {
        return this.$(eles);
      } else if (elementOrCollection(eles)) {
        return eles.collection();
      } else if (array(eles)) {
        if (!opts) {
          opts = {};
        }
        return new Collection(this, eles, opts.unique, opts.removed);
      }
      return new Collection(this);
    },
    nodes: function nodes(selector) {
      var nodes = this.$(function (ele) {
        return ele.isNode();
      });
      if (selector) {
        return nodes.filter(selector);
      }
      return nodes;
    },
    edges: function edges(selector) {
      var edges = this.$(function (ele) {
        return ele.isEdge();
      });
      if (selector) {
        return edges.filter(selector);
      }
      return edges;
    },
    // search the graph like jQuery
    $: function $(selector) {
      var eles = this._private.elements;
      if (selector) {
        return eles.filter(selector);
      } else {
        return eles.spawnSelf();
      }
    },
    mutableElements: function mutableElements() {
      return this._private.elements;
    }
  };

  // aliases
  corefn$3.elements = corefn$3.filter = corefn$3.$;

  var styfn$8 = {};

  // keys for style blocks, e.g. ttfftt
  var TRUE = 't';
  var FALSE = 'f';

  // (potentially expensive calculation)
  // apply the style to the element based on
  // - its bypass
  // - what selectors match it
  styfn$8.apply = function (eles) {
    var self = this;
    var _p = self._private;
    var cy = _p.cy;
    var updatedEles = cy.collection();
    for (var ie = 0; ie < eles.length; ie++) {
      var ele = eles[ie];
      var cxtMeta = self.getContextMeta(ele);
      if (cxtMeta.empty) {
        continue;
      }
      var cxtStyle = self.getContextStyle(cxtMeta);
      var app = self.applyContextStyle(cxtMeta, cxtStyle, ele);
      if (ele._private.appliedInitStyle) {
        self.updateTransitions(ele, app.diffProps);
      } else {
        ele._private.appliedInitStyle = true;
      }
      var hintsDiff = self.updateStyleHints(ele);
      if (hintsDiff) {
        updatedEles.push(ele);
      }
    } // for elements

    return updatedEles;
  };
  styfn$8.getPropertiesDiff = function (oldCxtKey, newCxtKey) {
    var self = this;
    var cache = self._private.propDiffs = self._private.propDiffs || {};
    var dualCxtKey = oldCxtKey + '-' + newCxtKey;
    var cachedVal = cache[dualCxtKey];
    if (cachedVal) {
      return cachedVal;
    }
    var diffProps = [];
    var addedProp = {};
    for (var i = 0; i < self.length; i++) {
      var cxt = self[i];
      var oldHasCxt = oldCxtKey[i] === TRUE;
      var newHasCxt = newCxtKey[i] === TRUE;
      var cxtHasDiffed = oldHasCxt !== newHasCxt;
      var cxtHasMappedProps = cxt.mappedProperties.length > 0;
      if (cxtHasDiffed || newHasCxt && cxtHasMappedProps) {
        var props = void 0;
        if (cxtHasDiffed && cxtHasMappedProps) {
          props = cxt.properties; // suffices b/c mappedProperties is a subset of properties
        } else if (cxtHasDiffed) {
          props = cxt.properties; // need to check them all
        } else if (cxtHasMappedProps) {
          props = cxt.mappedProperties; // only need to check mapped
        }

        for (var j = 0; j < props.length; j++) {
          var prop = props[j];
          var name = prop.name;

          // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter
          // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result
          // is cached)
          var laterCxtOverrides = false;
          for (var k = i + 1; k < self.length; k++) {
            var laterCxt = self[k];
            var hasLaterCxt = newCxtKey[k] === TRUE;
            if (!hasLaterCxt) {
              continue;
            } // can't override unless the context is active

            laterCxtOverrides = laterCxt.properties[prop.name] != null;
            if (laterCxtOverrides) {
              break;
            } // exit early as long as one later context overrides
          }

          if (!addedProp[name] && !laterCxtOverrides) {
            addedProp[name] = true;
            diffProps.push(name);
          }
        } // for props
      } // if
    } // for contexts

    cache[dualCxtKey] = diffProps;
    return diffProps;
  };
  styfn$8.getContextMeta = function (ele) {
    var self = this;
    var cxtKey = '';
    var diffProps;
    var prevKey = ele._private.styleCxtKey || '';

    // get the cxt key
    for (var i = 0; i < self.length; i++) {
      var context = self[i];
      var contextSelectorMatches = context.selector && context.selector.matches(ele); // NB: context.selector may be null for 'core'

      if (contextSelectorMatches) {
        cxtKey += TRUE;
      } else {
        cxtKey += FALSE;
      }
    } // for context

    diffProps = self.getPropertiesDiff(prevKey, cxtKey);
    ele._private.styleCxtKey = cxtKey;
    return {
      key: cxtKey,
      diffPropNames: diffProps,
      empty: diffProps.length === 0
    };
  };

  // gets a computed ele style object based on matched contexts
  styfn$8.getContextStyle = function (cxtMeta) {
    var cxtKey = cxtMeta.key;
    var self = this;
    var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};

    // if already computed style, returned cached copy
    if (cxtStyles[cxtKey]) {
      return cxtStyles[cxtKey];
    }
    var style = {
      _private: {
        key: cxtKey
      }
    };
    for (var i = 0; i < self.length; i++) {
      var cxt = self[i];
      var hasCxt = cxtKey[i] === TRUE;
      if (!hasCxt) {
        continue;
      }
      for (var j = 0; j < cxt.properties.length; j++) {
        var prop = cxt.properties[j];
        style[prop.name] = prop;
      }
    }
    cxtStyles[cxtKey] = style;
    return style;
  };
  styfn$8.applyContextStyle = function (cxtMeta, cxtStyle, ele) {
    var self = this;
    var diffProps = cxtMeta.diffPropNames;
    var retDiffProps = {};
    var types = self.types;
    for (var i = 0; i < diffProps.length; i++) {
      var diffPropName = diffProps[i];
      var cxtProp = cxtStyle[diffPropName];
      var eleProp = ele.pstyle(diffPropName);
      if (!cxtProp) {
        // no context prop means delete
        if (!eleProp) {
          continue; // no existing prop means nothing needs to be removed
          // nb affects initial application on mapped values like control-point-distances
        } else if (eleProp.bypass) {
          cxtProp = {
            name: diffPropName,
            deleteBypassed: true
          };
        } else {
          cxtProp = {
            name: diffPropName,
            "delete": true
          };
        }
      }

      // save cycles when the context prop doesn't need to be applied
      if (eleProp === cxtProp) {
        continue;
      }

      // save cycles when a mapped context prop doesn't need to be applied
      if (cxtProp.mapped === types.fn // context prop is function mapper
      && eleProp != null // some props can be null even by default (e.g. a prop that overrides another one)
      && eleProp.mapping != null // ele prop is a concrete value from from a mapper
      && eleProp.mapping.value === cxtProp.value // the current prop on the ele is a flat prop value for the function mapper
      ) {
        // NB don't write to cxtProp, as it's shared among eles (stored in stylesheet)
        var mapping = eleProp.mapping; // can write to mapping, as it's a per-ele copy
        var fnValue = mapping.fnValue = cxtProp.value(ele); // temporarily cache the value in case of a miss

        if (fnValue === mapping.prevFnValue) {
          continue;
        }
      }
      var retDiffProp = retDiffProps[diffPropName] = {
        prev: eleProp
      };
      self.applyParsedProperty(ele, cxtProp);
      retDiffProp.next = ele.pstyle(diffPropName);
      if (retDiffProp.next && retDiffProp.next.bypass) {
        retDiffProp.next = retDiffProp.next.bypassed;
      }
    }
    return {
      diffProps: retDiffProps
    };
  };
  styfn$8.updateStyleHints = function (ele) {
    var _p = ele._private;
    var self = this;
    var propNames = self.propertyGroupNames;
    var propGrKeys = self.propertyGroupKeys;
    var propHash = function propHash(ele, propNames, seedKey) {
      return self.getPropertiesHash(ele, propNames, seedKey);
    };
    var oldStyleKey = _p.styleKey;
    if (ele.removed()) {
      return false;
    }
    var isNode = _p.group === 'nodes';

    // get the style key hashes per prop group
    // but lazily -- only use non-default prop values to reduce the number of hashes
    //

    var overriddenStyles = ele._private.style;
    propNames = Object.keys(overriddenStyles);
    for (var i = 0; i < propGrKeys.length; i++) {
      var grKey = propGrKeys[i];
      _p.styleKeys[grKey] = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];
    }
    var updateGrKey1 = function updateGrKey1(val, grKey) {
      return _p.styleKeys[grKey][0] = hashInt(val, _p.styleKeys[grKey][0]);
    };
    var updateGrKey2 = function updateGrKey2(val, grKey) {
      return _p.styleKeys[grKey][1] = hashIntAlt(val, _p.styleKeys[grKey][1]);
    };
    var updateGrKey = function updateGrKey(val, grKey) {
      updateGrKey1(val, grKey);
      updateGrKey2(val, grKey);
    };
    var updateGrKeyWStr = function updateGrKeyWStr(strVal, grKey) {
      for (var j = 0; j < strVal.length; j++) {
        var ch = strVal.charCodeAt(j);
        updateGrKey1(ch, grKey);
        updateGrKey2(ch, grKey);
      }
    };

    // - hashing works on 32 bit ints b/c we use bitwise ops
    // - small numbers get cut off (e.g. 0.123 is seen as 0 by the hashing function)
    // - raise up small numbers so more significant digits are seen by hashing
    // - make small numbers larger than a normal value to avoid collisions
    // - works in practice and it's relatively cheap
    var N = 2000000000;
    var cleanNum = function cleanNum(val) {
      return -128 < val && val < 128 && Math.floor(val) !== val ? N - (val * 1024 | 0) : val;
    };
    for (var _i = 0; _i < propNames.length; _i++) {
      var name = propNames[_i];
      var parsedProp = overriddenStyles[name];
      if (parsedProp == null) {
        continue;
      }
      var propInfo = this.properties[name];
      var type = propInfo.type;
      var _grKey = propInfo.groupKey;
      var normalizedNumberVal = void 0;
      if (propInfo.hashOverride != null) {
        normalizedNumberVal = propInfo.hashOverride(ele, parsedProp);
      } else if (parsedProp.pfValue != null) {
        normalizedNumberVal = parsedProp.pfValue;
      }

      // might not be a number if it allows enums
      var numberVal = propInfo.enums == null ? parsedProp.value : null;
      var haveNormNum = normalizedNumberVal != null;
      var haveUnitedNum = numberVal != null;
      var haveNum = haveNormNum || haveUnitedNum;
      var units = parsedProp.units;

      // numbers are cheaper to hash than strings
      // 1 hash op vs n hash ops (for length n string)
      if (type.number && haveNum && !type.multiple) {
        var v = haveNormNum ? normalizedNumberVal : numberVal;
        updateGrKey(cleanNum(v), _grKey);
        if (!haveNormNum && units != null) {
          updateGrKeyWStr(units, _grKey);
        }
      } else {
        updateGrKeyWStr(parsedProp.strValue, _grKey);
      }
    }

    // overall style key
    //

    var hash = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];
    for (var _i2 = 0; _i2 < propGrKeys.length; _i2++) {
      var _grKey2 = propGrKeys[_i2];
      var grHash = _p.styleKeys[_grKey2];
      hash[0] = hashInt(grHash[0], hash[0]);
      hash[1] = hashIntAlt(grHash[1], hash[1]);
    }
    _p.styleKey = combineHashes(hash[0], hash[1]);

    // label dims
    //

    var sk = _p.styleKeys;
    _p.labelDimsKey = combineHashesArray(sk.labelDimensions);
    var labelKeys = propHash(ele, ['label'], sk.labelDimensions);
    _p.labelKey = combineHashesArray(labelKeys);
    _p.labelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, labelKeys));
    if (!isNode) {
      var sourceLabelKeys = propHash(ele, ['source-label'], sk.labelDimensions);
      _p.sourceLabelKey = combineHashesArray(sourceLabelKeys);
      _p.sourceLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, sourceLabelKeys));
      var targetLabelKeys = propHash(ele, ['target-label'], sk.labelDimensions);
      _p.targetLabelKey = combineHashesArray(targetLabelKeys);
      _p.targetLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, targetLabelKeys));
    }

    // node
    //

    if (isNode) {
      var _p$styleKeys = _p.styleKeys,
        nodeBody = _p$styleKeys.nodeBody,
        nodeBorder = _p$styleKeys.nodeBorder,
        nodeOutline = _p$styleKeys.nodeOutline,
        backgroundImage = _p$styleKeys.backgroundImage,
        compound = _p$styleKeys.compound,
        pie = _p$styleKeys.pie;
      var nodeKeys = [nodeBody, nodeBorder, nodeOutline, backgroundImage, compound, pie].filter(function (k) {
        return k != null;
      }).reduce(hashArrays, [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]);
      _p.nodeKey = combineHashesArray(nodeKeys);
      _p.hasPie = pie != null && pie[0] !== DEFAULT_HASH_SEED && pie[1] !== DEFAULT_HASH_SEED_ALT;
    }
    return oldStyleKey !== _p.styleKey;
  };
  styfn$8.clearStyleHints = function (ele) {
    var _p = ele._private;
    _p.styleCxtKey = '';
    _p.styleKeys = {};
    _p.styleKey = null;
    _p.labelKey = null;
    _p.labelStyleKey = null;
    _p.sourceLabelKey = null;
    _p.sourceLabelStyleKey = null;
    _p.targetLabelKey = null;
    _p.targetLabelStyleKey = null;
    _p.nodeKey = null;
    _p.hasPie = null;
  };

  // apply a property to the style (for internal use)
  // returns whether application was successful
  //
  // now, this function flattens the property, and here's how:
  //
  // for parsedProp:{ bypass: true, deleteBypass: true }
  // no property is generated, instead the bypass property in the
  // element's style is replaced by what's pointed to by the `bypassed`
  // field in the bypass property (i.e. restoring the property the
  // bypass was overriding)
  //
  // for parsedProp:{ mapped: truthy }
  // the generated flattenedProp:{ mapping: prop }
  //
  // for parsedProp:{ bypass: true }
  // the generated flattenedProp:{ bypassed: parsedProp }
  styfn$8.applyParsedProperty = function (ele, parsedProp) {
    var self = this;
    var prop = parsedProp;
    var style = ele._private.style;
    var flatProp;
    var types = self.types;
    var type = self.properties[prop.name].type;
    var propIsBypass = prop.bypass;
    var origProp = style[prop.name];
    var origPropIsBypass = origProp && origProp.bypass;
    var _p = ele._private;
    var flatPropMapping = 'mapping';
    var getVal = function getVal(p) {
      if (p == null) {
        return null;
      } else if (p.pfValue != null) {
        return p.pfValue;
      } else {
        return p.value;
      }
    };
    var checkTriggers = function checkTriggers() {
      var fromVal = getVal(origProp);
      var toVal = getVal(prop);
      self.checkTriggers(ele, prop.name, fromVal, toVal);
    };

    // edge sanity checks to prevent the client from making serious mistakes
    if (parsedProp.name === 'curve-style' && ele.isEdge() && (
    // loops must be bundled beziers
    parsedProp.value !== 'bezier' && ele.isLoop() ||
    // edges connected to compound nodes can not be haystacks
    parsedProp.value === 'haystack' && (ele.source().isParent() || ele.target().isParent()))) {
      prop = parsedProp = this.parse(parsedProp.name, 'bezier', propIsBypass);
    }
    if (prop["delete"]) {
      // delete the property and use the default value on falsey value
      style[prop.name] = undefined;
      checkTriggers();
      return true;
    }
    if (prop.deleteBypassed) {
      // delete the property that the
      if (!origProp) {
        checkTriggers();
        return true; // can't delete if no prop
      } else if (origProp.bypass) {
        // delete bypassed
        origProp.bypassed = undefined;
        checkTriggers();
        return true;
      } else {
        return false; // we're unsuccessful deleting the bypassed
      }
    }

    // check if we need to delete the current bypass
    if (prop.deleteBypass) {
      // then this property is just here to indicate we need to delete
      if (!origProp) {
        checkTriggers();
        return true; // property is already not defined
      } else if (origProp.bypass) {
        // then replace the bypass property with the original
        // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)
        style[prop.name] = origProp.bypassed;
        checkTriggers();
        return true;
      } else {
        return false; // we're unsuccessful deleting the bypass
      }
    }

    var printMappingErr = function printMappingErr() {
      warn('Do not assign mappings to elements without corresponding data (i.e. ele `' + ele.id() + '` has no mapping for property `' + prop.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop.field + '` defined');
    };

    // put the property in the style objects
    switch (prop.mapped) {
      // flatten the property if mapped
      case types.mapData:
        {
          // flatten the field (e.g. data.foo.bar)
          var fields = prop.field.split('.');
          var fieldVal = _p.data;
          for (var i = 0; i < fields.length && fieldVal; i++) {
            var field = fields[i];
            fieldVal = fieldVal[field];
          }
          if (fieldVal == null) {
            printMappingErr();
            return false;
          }
          var percent;
          if (!number$1(fieldVal)) {
            // then don't apply and fall back on the existing style
            warn('Do not use continuous mappers without specifying numeric data (i.e. `' + prop.field + ': ' + fieldVal + '` for `' + ele.id() + '` is non-numeric)');
            return false;
          } else {
            var fieldWidth = prop.fieldMax - prop.fieldMin;
            if (fieldWidth === 0) {
              // safety check -- not strictly necessary as no props of zero range should be passed here
              percent = 0;
            } else {
              percent = (fieldVal - prop.fieldMin) / fieldWidth;
            }
          }

          // make sure to bound percent value
          if (percent < 0) {
            percent = 0;
          } else if (percent > 1) {
            percent = 1;
          }
          if (type.color) {
            var r1 = prop.valueMin[0];
            var r2 = prop.valueMax[0];
            var g1 = prop.valueMin[1];
            var g2 = prop.valueMax[1];
            var b1 = prop.valueMin[2];
            var b2 = prop.valueMax[2];
            var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];
            var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];
            var clr = [Math.round(r1 + (r2 - r1) * percent), Math.round(g1 + (g2 - g1) * percent), Math.round(b1 + (b2 - b1) * percent), Math.round(a1 + (a2 - a1) * percent)];
            flatProp = {
              // colours are simple, so just create the flat property instead of expensive string parsing
              bypass: prop.bypass,
              // we're a bypass if the mapping property is a bypass
              name: prop.name,
              value: clr,
              strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'
            };
          } else if (type.number) {
            var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;
            flatProp = this.parse(prop.name, calcValue, prop.bypass, flatPropMapping);
          } else {
            return false; // can only map to colours and numbers
          }

          if (!flatProp) {
            // if we can't flatten the property, then don't apply the property and fall back on the existing style
            printMappingErr();
            return false;
          }
          flatProp.mapping = prop; // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }

      // direct mapping
      case types.data:
        {
          // flatten the field (e.g. data.foo.bar)
          var _fields = prop.field.split('.');
          var _fieldVal = _p.data;
          for (var _i3 = 0; _i3 < _fields.length && _fieldVal; _i3++) {
            var _field = _fields[_i3];
            _fieldVal = _fieldVal[_field];
          }
          if (_fieldVal != null) {
            flatProp = this.parse(prop.name, _fieldVal, prop.bypass, flatPropMapping);
          }
          if (!flatProp) {
            // if we can't flatten the property, then don't apply and fall back on the existing style
            printMappingErr();
            return false;
          }
          flatProp.mapping = prop; // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }
      case types.fn:
        {
          var fn = prop.value;
          var fnRetVal = prop.fnValue != null ? prop.fnValue : fn(ele); // check for cached value before calling function

          prop.prevFnValue = fnRetVal;
          if (fnRetVal == null) {
            warn('Custom function mappers may not return null (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is null)');
            return false;
          }
          flatProp = this.parse(prop.name, fnRetVal, prop.bypass, flatPropMapping);
          if (!flatProp) {
            warn('Custom function mappers may not return invalid values for the property type (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is invalid)');
            return false;
          }
          flatProp.mapping = copy(prop); // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }
      case undefined:
        break;
      // just set the property

      default:
        return false;
      // not a valid mapping
    }

    // if the property is a bypass property, then link the resultant property to the original one
    if (propIsBypass) {
      if (origPropIsBypass) {
        // then this bypass overrides the existing one
        prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass
      } else {
        // then link the orig prop to the new bypass
        prop.bypassed = origProp;
      }
      style[prop.name] = prop; // and set
    } else {
      // prop is not bypass
      if (origPropIsBypass) {
        // then keep the orig prop (since it's a bypass) and link to the new prop
        origProp.bypassed = prop;
      } else {
        // then just replace the old prop with the new one
        style[prop.name] = prop;
      }
    }
    checkTriggers();
    return true;
  };
  styfn$8.cleanElements = function (eles, keepBypasses) {
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      this.clearStyleHints(ele);
      ele.dirtyCompoundBoundsCache();
      ele.dirtyBoundingBoxCache();
      if (!keepBypasses) {
        ele._private.style = {};
      } else {
        var style = ele._private.style;
        var propNames = Object.keys(style);
        for (var j = 0; j < propNames.length; j++) {
          var propName = propNames[j];
          var eleProp = style[propName];
          if (eleProp != null) {
            if (eleProp.bypass) {
              eleProp.bypassed = null;
            } else {
              style[propName] = null;
            }
          }
        }
      }
    }
  };

  // updates the visual style for all elements (useful for manual style modification after init)
  styfn$8.update = function () {
    var cy = this._private.cy;
    var eles = cy.mutableElements();
    eles.updateStyle();
  };

  // diffProps : { name => { prev, next } }
  styfn$8.updateTransitions = function (ele, diffProps) {
    var self = this;
    var _p = ele._private;
    var props = ele.pstyle('transition-property').value;
    var duration = ele.pstyle('transition-duration').pfValue;
    var delay = ele.pstyle('transition-delay').pfValue;
    if (props.length > 0 && duration > 0) {
      var style = {};

      // build up the style to animate towards
      var anyPrev = false;
      for (var i = 0; i < props.length; i++) {
        var prop = props[i];
        var styProp = ele.pstyle(prop);
        var diffProp = diffProps[prop];
        if (!diffProp) {
          continue;
        }
        var prevProp = diffProp.prev;
        var fromProp = prevProp;
        var toProp = diffProp.next != null ? diffProp.next : styProp;
        var diff = false;
        var initVal = void 0;
        var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)

        if (!fromProp) {
          continue;
        }

        // consider px values
        if (number$1(fromProp.pfValue) && number$1(toProp.pfValue)) {
          diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy
          initVal = fromProp.pfValue + initDt * diff;

          // consider numerical values
        } else if (number$1(fromProp.value) && number$1(toProp.value)) {
          diff = toProp.value - fromProp.value; // nonzero is truthy
          initVal = fromProp.value + initDt * diff;

          // consider colour values
        } else if (array(fromProp.value) && array(toProp.value)) {
          diff = fromProp.value[0] !== toProp.value[0] || fromProp.value[1] !== toProp.value[1] || fromProp.value[2] !== toProp.value[2];
          initVal = fromProp.strValue;
        }

        // the previous value is good for an animation only if it's different
        if (diff) {
          style[prop] = toProp.strValue; // to val
          this.applyBypass(ele, prop, initVal); // from val
          anyPrev = true;
        }
      } // end if props allow ani

      // can't transition if there's nothing previous to transition from
      if (!anyPrev) {
        return;
      }
      _p.transitioning = true;
      new Promise$1(function (resolve) {
        if (delay > 0) {
          ele.delayAnimation(delay).play().promise().then(resolve);
        } else {
          resolve();
        }
      }).then(function () {
        return ele.animation({
          style: style,
          duration: duration,
          easing: ele.pstyle('transition-timing-function').value,
          queue: false
        }).play().promise();
      }).then(function () {
        // if( !isBypass ){
        self.removeBypasses(ele, props);
        ele.emitAndNotify('style');
        // }

        _p.transitioning = false;
      });
    } else if (_p.transitioning) {
      this.removeBypasses(ele, props);
      ele.emitAndNotify('style');
      _p.transitioning = false;
    }
  };
  styfn$8.checkTrigger = function (ele, name, fromValue, toValue, getTrigger, onTrigger) {
    var prop = this.properties[name];
    var triggerCheck = getTrigger(prop);
    if (triggerCheck != null && triggerCheck(fromValue, toValue)) {
      onTrigger(prop);
    }
  };
  styfn$8.checkZOrderTrigger = function (ele, name, fromValue, toValue) {
    var _this = this;
    this.checkTrigger(ele, name, fromValue, toValue, function (prop) {
      return prop.triggersZOrder;
    }, function () {
      _this._private.cy.notify('zorder', ele);
    });
  };
  styfn$8.checkBoundsTrigger = function (ele, name, fromValue, toValue) {
    this.checkTrigger(ele, name, fromValue, toValue, function (prop) {
      return prop.triggersBounds;
    }, function (prop) {
      ele.dirtyCompoundBoundsCache();
      ele.dirtyBoundingBoxCache();

      // if the prop change makes the bb of pll bezier edges invalid,
      // then dirty the pll edge bb cache as well
      if (
      // only for beziers -- so performance of other edges isn't affected
      prop.triggersBoundsOfParallelBeziers && name === 'curve-style' && (fromValue === 'bezier' || toValue === 'bezier')) {
        ele.parallelEdges().forEach(function (pllEdge) {
          if (pllEdge.isBundledBezier()) {
            pllEdge.dirtyBoundingBoxCache();
          }
        });
      }
      if (prop.triggersBoundsOfConnectedEdges && name === 'display' && (fromValue === 'none' || toValue === 'none')) {
        ele.connectedEdges().forEach(function (edge) {
          edge.dirtyBoundingBoxCache();
        });
      }
    });
  };
  styfn$8.checkTriggers = function (ele, name, fromValue, toValue) {
    ele.dirtyStyleCache();
    this.checkZOrderTrigger(ele, name, fromValue, toValue);
    this.checkBoundsTrigger(ele, name, fromValue, toValue);
  };

  var styfn$7 = {};

  // bypasses are applied to an existing style on an element, and just tacked on temporarily
  // returns true iff application was successful for at least 1 specified property
  styfn$7.applyBypass = function (eles, name, value, updateTransitions) {
    var self = this;
    var props = [];
    var isBypass = true;

    // put all the properties (can specify one or many) in an array after parsing them
    if (name === '*' || name === '**') {
      // apply to all property names

      if (value !== undefined) {
        for (var i = 0; i < self.properties.length; i++) {
          var prop = self.properties[i];
          var _name = prop.name;
          var parsedProp = this.parse(_name, value, true);
          if (parsedProp) {
            props.push(parsedProp);
          }
        }
      }
    } else if (string(name)) {
      // then parse the single property
      var _parsedProp = this.parse(name, value, true);
      if (_parsedProp) {
        props.push(_parsedProp);
      }
    } else if (plainObject(name)) {
      // then parse each property
      var specifiedProps = name;
      updateTransitions = value;
      var names = Object.keys(specifiedProps);
      for (var _i = 0; _i < names.length; _i++) {
        var _name2 = names[_i];
        var _value = specifiedProps[_name2];
        if (_value === undefined) {
          // try camel case name too
          _value = specifiedProps[dash2camel(_name2)];
        }
        if (_value !== undefined) {
          var _parsedProp2 = this.parse(_name2, _value, true);
          if (_parsedProp2) {
            props.push(_parsedProp2);
          }
        }
      }
    } else {
      // can't do anything without well defined properties
      return false;
    }

    // we've failed if there are no valid properties
    if (props.length === 0) {
      return false;
    }

    // now, apply the bypass properties on the elements
    var ret = false; // return true if at least one succesful bypass applied
    for (var _i2 = 0; _i2 < eles.length; _i2++) {
      // for each ele
      var ele = eles[_i2];
      var diffProps = {};
      var diffProp = void 0;
      for (var j = 0; j < props.length; j++) {
        // for each prop
        var _prop = props[j];
        if (updateTransitions) {
          var prevProp = ele.pstyle(_prop.name);
          diffProp = diffProps[_prop.name] = {
            prev: prevProp
          };
        }
        ret = this.applyParsedProperty(ele, copy(_prop)) || ret;
        if (updateTransitions) {
          diffProp.next = ele.pstyle(_prop.name);
        }
      } // for props

      if (ret) {
        this.updateStyleHints(ele);
      }
      if (updateTransitions) {
        this.updateTransitions(ele, diffProps, isBypass);
      }
    } // for eles

    return ret;
  };

  // only useful in specific cases like animation
  styfn$7.overrideBypass = function (eles, name, value) {
    name = camel2dash(name);
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var prop = ele._private.style[name];
      var type = this.properties[name].type;
      var isColor = type.color;
      var isMulti = type.mutiple;
      var oldValue = !prop ? null : prop.pfValue != null ? prop.pfValue : prop.value;
      if (!prop || !prop.bypass) {
        // need a bypass if one doesn't exist
        this.applyBypass(ele, name, value);
      } else {
        prop.value = value;
        if (prop.pfValue != null) {
          prop.pfValue = value;
        }
        if (isColor) {
          prop.strValue = 'rgb(' + value.join(',') + ')';
        } else if (isMulti) {
          prop.strValue = value.join(' ');
        } else {
          prop.strValue = '' + value;
        }
        this.updateStyleHints(ele);
      }
      this.checkTriggers(ele, name, oldValue, value);
    }
  };
  styfn$7.removeAllBypasses = function (eles, updateTransitions) {
    return this.removeBypasses(eles, this.propertyNames, updateTransitions);
  };
  styfn$7.removeBypasses = function (eles, props, updateTransitions) {
    var isBypass = true;
    for (var j = 0; j < eles.length; j++) {
      var ele = eles[j];
      var diffProps = {};
      for (var i = 0; i < props.length; i++) {
        var name = props[i];
        var prop = this.properties[name];
        var prevProp = ele.pstyle(prop.name);
        if (!prevProp || !prevProp.bypass) {
          // if a bypass doesn't exist for the prop, nothing needs to be removed
          continue;
        }
        var value = ''; // empty => remove bypass
        var parsedProp = this.parse(name, value, true);
        var diffProp = diffProps[prop.name] = {
          prev: prevProp
        };
        this.applyParsedProperty(ele, parsedProp);
        diffProp.next = ele.pstyle(prop.name);
      } // for props

      this.updateStyleHints(ele);
      if (updateTransitions) {
        this.updateTransitions(ele, diffProps, isBypass);
      }
    } // for eles
  };

  var styfn$6 = {};

  // gets what an em size corresponds to in pixels relative to a dom element
  styfn$6.getEmSizeInPixels = function () {
    var px = this.containerCss('font-size');
    if (px != null) {
      return parseFloat(px);
    } else {
      return 1; // for headless
    }
  };

  // gets css property from the core container
  styfn$6.containerCss = function (propName) {
    var cy = this._private.cy;
    var domElement = cy.container();
    var containerWindow = cy.window();
    if (containerWindow && domElement && containerWindow.getComputedStyle) {
      return containerWindow.getComputedStyle(domElement).getPropertyValue(propName);
    }
  };

  var styfn$5 = {};

  // gets the rendered style for an element
  styfn$5.getRenderedStyle = function (ele, prop) {
    if (prop) {
      return this.getStylePropertyValue(ele, prop, true);
    } else {
      return this.getRawStyle(ele, true);
    }
  };

  // gets the raw style for an element
  styfn$5.getRawStyle = function (ele, isRenderedVal) {
    var self = this;
    ele = ele[0]; // insure it's an element

    if (ele) {
      var rstyle = {};
      for (var i = 0; i < self.properties.length; i++) {
        var prop = self.properties[i];
        var val = self.getStylePropertyValue(ele, prop.name, isRenderedVal);
        if (val != null) {
          rstyle[prop.name] = val;
          rstyle[dash2camel(prop.name)] = val;
        }
      }
      return rstyle;
    }
  };
  styfn$5.getIndexedStyle = function (ele, property, subproperty, index) {
    var pstyle = ele.pstyle(property)[subproperty][index];
    return pstyle != null ? pstyle : ele.cy().style().getDefaultProperty(property)[subproperty][0];
  };
  styfn$5.getStylePropertyValue = function (ele, propName, isRenderedVal) {
    var self = this;
    ele = ele[0]; // insure it's an element

    if (ele) {
      var prop = self.properties[propName];
      if (prop.alias) {
        prop = prop.pointsTo;
      }
      var type = prop.type;
      var styleProp = ele.pstyle(prop.name);
      if (styleProp) {
        var value = styleProp.value,
          units = styleProp.units,
          strValue = styleProp.strValue;
        if (isRenderedVal && type.number && value != null && number$1(value)) {
          var zoom = ele.cy().zoom();
          var getRenderedValue = function getRenderedValue(val) {
            return val * zoom;
          };
          var getValueStringWithUnits = function getValueStringWithUnits(val, units) {
            return getRenderedValue(val) + units;
          };
          var isArrayValue = array(value);
          var haveUnits = isArrayValue ? units.every(function (u) {
            return u != null;
          }) : units != null;
          if (haveUnits) {
            if (isArrayValue) {
              return value.map(function (v, i) {
                return getValueStringWithUnits(v, units[i]);
              }).join(' ');
            } else {
              return getValueStringWithUnits(value, units);
            }
          } else {
            if (isArrayValue) {
              return value.map(function (v) {
                return string(v) ? v : '' + getRenderedValue(v);
              }).join(' ');
            } else {
              return '' + getRenderedValue(value);
            }
          }
        } else if (strValue != null) {
          return strValue;
        }
      }
      return null;
    }
  };
  styfn$5.getAnimationStartStyle = function (ele, aniProps) {
    var rstyle = {};
    for (var i = 0; i < aniProps.length; i++) {
      var aniProp = aniProps[i];
      var name = aniProp.name;
      var styleProp = ele.pstyle(name);
      if (styleProp !== undefined) {
        // then make a prop of it
        if (plainObject(styleProp)) {
          styleProp = this.parse(name, styleProp.strValue);
        } else {
          styleProp = this.parse(name, styleProp);
        }
      }
      if (styleProp) {
        rstyle[name] = styleProp;
      }
    }
    return rstyle;
  };
  styfn$5.getPropsList = function (propsObj) {
    var self = this;
    var rstyle = [];
    var style = propsObj;
    var props = self.properties;
    if (style) {
      var names = Object.keys(style);
      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        var val = style[name];
        var prop = props[name] || props[camel2dash(name)];
        var styleProp = this.parse(prop.name, val);
        if (styleProp) {
          rstyle.push(styleProp);
        }
      }
    }
    return rstyle;
  };
  styfn$5.getNonDefaultPropertiesHash = function (ele, propNames, seed) {
    var hash = seed.slice();
    var name, val, strVal, chVal;
    var i, j;
    for (i = 0; i < propNames.length; i++) {
      name = propNames[i];
      val = ele.pstyle(name, false);
      if (val == null) {
        continue;
      } else if (val.pfValue != null) {
        hash[0] = hashInt(chVal, hash[0]);
        hash[1] = hashIntAlt(chVal, hash[1]);
      } else {
        strVal = val.strValue;
        for (j = 0; j < strVal.length; j++) {
          chVal = strVal.charCodeAt(j);
          hash[0] = hashInt(chVal, hash[0]);
          hash[1] = hashIntAlt(chVal, hash[1]);
        }
      }
    }
    return hash;
  };
  styfn$5.getPropertiesHash = styfn$5.getNonDefaultPropertiesHash;

  var styfn$4 = {};
  styfn$4.appendFromJson = function (json) {
    var style = this;
    for (var i = 0; i < json.length; i++) {
      var context = json[i];
      var selector = context.selector;
      var props = context.style || context.css;
      var names = Object.keys(props);
      style.selector(selector); // apply selector

      for (var j = 0; j < names.length; j++) {
        var name = names[j];
        var value = props[name];
        style.css(name, value); // apply property
      }
    }

    return style;
  };

  // accessible cy.style() function
  styfn$4.fromJson = function (json) {
    var style = this;
    style.resetToDefault();
    style.appendFromJson(json);
    return style;
  };

  // get json from cy.style() api
  styfn$4.json = function () {
    var json = [];
    for (var i = this.defaultLength; i < this.length; i++) {
      var cxt = this[i];
      var selector = cxt.selector;
      var props = cxt.properties;
      var css = {};
      for (var j = 0; j < props.length; j++) {
        var prop = props[j];
        css[prop.name] = prop.strValue;
      }
      json.push({
        selector: !selector ? 'core' : selector.toString(),
        style: css
      });
    }
    return json;
  };

  var styfn$3 = {};
  styfn$3.appendFromString = function (string) {
    var self = this;
    var style = this;
    var remaining = '' + string;
    var selAndBlockStr;
    var blockRem;
    var propAndValStr;

    // remove comments from the style string
    remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, '');
    function removeSelAndBlockFromRemaining() {
      // remove the parsed selector and block from the remaining text to parse
      if (remaining.length > selAndBlockStr.length) {
        remaining = remaining.substr(selAndBlockStr.length);
      } else {
        remaining = '';
      }
    }
    function removePropAndValFromRem() {
      // remove the parsed property and value from the remaining block text to parse
      if (blockRem.length > propAndValStr.length) {
        blockRem = blockRem.substr(propAndValStr.length);
      } else {
        blockRem = '';
      }
    }
    for (;;) {
      var nothingLeftToParse = remaining.match(/^\s*$/);
      if (nothingLeftToParse) {
        break;
      }
      var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);
      if (!selAndBlock) {
        warn('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining);
        break;
      }
      selAndBlockStr = selAndBlock[0];

      // parse the selector
      var selectorStr = selAndBlock[1];
      if (selectorStr !== 'core') {
        var selector = new Selector(selectorStr);
        if (selector.invalid) {
          warn('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr);

          // skip this selector and block
          removeSelAndBlockFromRemaining();
          continue;
        }
      }

      // parse the block of properties and values
      var blockStr = selAndBlock[2];
      var invalidBlock = false;
      blockRem = blockStr;
      var props = [];
      for (;;) {
        var _nothingLeftToParse = blockRem.match(/^\s*$/);
        if (_nothingLeftToParse) {
          break;
        }
        var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);
        if (!propAndVal) {
          warn('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr);
          invalidBlock = true;
          break;
        }
        propAndValStr = propAndVal[0];
        var propStr = propAndVal[1];
        var valStr = propAndVal[2];
        var prop = self.properties[propStr];
        if (!prop) {
          warn('Skipping property: Invalid property name in: ' + propAndValStr);

          // skip this property in the block
          removePropAndValFromRem();
          continue;
        }
        var parsedProp = style.parse(propStr, valStr);
        if (!parsedProp) {
          warn('Skipping property: Invalid property definition in: ' + propAndValStr);

          // skip this property in the block
          removePropAndValFromRem();
          continue;
        }
        props.push({
          name: propStr,
          val: valStr
        });
        removePropAndValFromRem();
      }
      if (invalidBlock) {
        removeSelAndBlockFromRemaining();
        break;
      }

      // put the parsed block in the style
      style.selector(selectorStr);
      for (var i = 0; i < props.length; i++) {
        var _prop = props[i];
        style.css(_prop.name, _prop.val);
      }
      removeSelAndBlockFromRemaining();
    }
    return style;
  };
  styfn$3.fromString = function (string) {
    var style = this;
    style.resetToDefault();
    style.appendFromString(string);
    return style;
  };

  var styfn$2 = {};
  (function () {
    var number$1 = number;
    var rgba = rgbaNoBackRefs;
    var hsla = hslaNoBackRefs;
    var hex3$1 = hex3;
    var hex6$1 = hex6;
    var data = function data(prefix) {
      return '^' + prefix + '\\s*\\(\\s*([\\w\\.]+)\\s*\\)$';
    };
    var mapData = function mapData(prefix) {
      var mapArg = number$1 + '|\\w+|' + rgba + '|' + hsla + '|' + hex3$1 + '|' + hex6$1;
      return '^' + prefix + '\\s*\\(([\\w\\.]+)\\s*\\,\\s*(' + number$1 + ')\\s*\\,\\s*(' + number$1 + ')\\s*,\\s*(' + mapArg + ')\\s*\\,\\s*(' + mapArg + ')\\)$';
    };
    var urlRegexes = ['^url\\s*\\(\\s*[\'"]?(.+?)[\'"]?\\s*\\)$', '^(none)$', '^(.+)$'];

    // each visual style property has a type and needs to be validated according to it
    styfn$2.types = {
      time: {
        number: true,
        min: 0,
        units: 's|ms',
        implicitUnits: 'ms'
      },
      percent: {
        number: true,
        min: 0,
        max: 100,
        units: '%',
        implicitUnits: '%'
      },
      percentages: {
        number: true,
        min: 0,
        max: 100,
        units: '%',
        implicitUnits: '%',
        multiple: true
      },
      zeroOneNumber: {
        number: true,
        min: 0,
        max: 1,
        unitless: true
      },
      zeroOneNumbers: {
        number: true,
        min: 0,
        max: 1,
        unitless: true,
        multiple: true
      },
      nOneOneNumber: {
        number: true,
        min: -1,
        max: 1,
        unitless: true
      },
      nonNegativeInt: {
        number: true,
        min: 0,
        integer: true,
        unitless: true
      },
      nonNegativeNumber: {
        number: true,
        min: 0,
        unitless: true
      },
      position: {
        enums: ['parent', 'origin']
      },
      nodeSize: {
        number: true,
        min: 0,
        enums: ['label']
      },
      number: {
        number: true,
        unitless: true
      },
      numbers: {
        number: true,
        unitless: true,
        multiple: true
      },
      positiveNumber: {
        number: true,
        unitless: true,
        min: 0,
        strictMin: true
      },
      size: {
        number: true,
        min: 0
      },
      bidirectionalSize: {
        number: true
      },
      // allows negative
      bidirectionalSizeMaybePercent: {
        number: true,
        allowPercent: true
      },
      // allows negative
      bidirectionalSizes: {
        number: true,
        multiple: true
      },
      // allows negative
      sizeMaybePercent: {
        number: true,
        min: 0,
        allowPercent: true
      },
      axisDirection: {
        enums: ['horizontal', 'leftward', 'rightward', 'vertical', 'upward', 'downward', 'auto']
      },
      paddingRelativeTo: {
        enums: ['width', 'height', 'average', 'min', 'max']
      },
      bgWH: {
        number: true,
        min: 0,
        allowPercent: true,
        enums: ['auto'],
        multiple: true
      },
      bgPos: {
        number: true,
        allowPercent: true,
        multiple: true
      },
      bgRelativeTo: {
        enums: ['inner', 'include-padding'],
        multiple: true
      },
      bgRepeat: {
        enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'],
        multiple: true
      },
      bgFit: {
        enums: ['none', 'contain', 'cover'],
        multiple: true
      },
      bgCrossOrigin: {
        enums: ['anonymous', 'use-credentials', 'null'],
        multiple: true
      },
      bgClip: {
        enums: ['none', 'node'],
        multiple: true
      },
      bgContainment: {
        enums: ['inside', 'over'],
        multiple: true
      },
      color: {
        color: true
      },
      colors: {
        color: true,
        multiple: true
      },
      fill: {
        enums: ['solid', 'linear-gradient', 'radial-gradient']
      },
      bool: {
        enums: ['yes', 'no']
      },
      bools: {
        enums: ['yes', 'no'],
        multiple: true
      },
      lineStyle: {
        enums: ['solid', 'dotted', 'dashed']
      },
      lineCap: {
        enums: ['butt', 'round', 'square']
      },
      borderStyle: {
        enums: ['solid', 'dotted', 'dashed', 'double']
      },
      curveStyle: {
        enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments', 'straight', 'straight-triangle', 'taxi']
      },
      fontFamily: {
        regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'
      },
      fontStyle: {
        enums: ['italic', 'normal', 'oblique']
      },
      fontWeight: {
        enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900]
      },
      textDecoration: {
        enums: ['none', 'underline', 'overline', 'line-through']
      },
      textTransform: {
        enums: ['none', 'uppercase', 'lowercase']
      },
      textWrap: {
        enums: ['none', 'wrap', 'ellipsis']
      },
      textOverflowWrap: {
        enums: ['whitespace', 'anywhere']
      },
      textBackgroundShape: {
        enums: ['rectangle', 'roundrectangle', 'round-rectangle']
      },
      nodeShape: {
        enums: ['rectangle', 'roundrectangle', 'round-rectangle', 'cutrectangle', 'cut-rectangle', 'bottomroundrectangle', 'bottom-round-rectangle', 'barrel', 'ellipse', 'triangle', 'round-triangle', 'square', 'pentagon', 'round-pentagon', 'hexagon', 'round-hexagon', 'concavehexagon', 'concave-hexagon', 'heptagon', 'round-heptagon', 'octagon', 'round-octagon', 'tag', 'round-tag', 'star', 'diamond', 'round-diamond', 'vee', 'rhomboid', 'right-rhomboid', 'polygon']
      },
      overlayShape: {
        enums: ['roundrectangle', 'round-rectangle', 'ellipse']
      },
      compoundIncludeLabels: {
        enums: ['include', 'exclude']
      },
      arrowShape: {
        enums: ['tee', 'triangle', 'triangle-tee', 'circle-triangle', 'triangle-cross', 'triangle-backcurve', 'vee', 'square', 'circle', 'diamond', 'chevron', 'none']
      },
      arrowFill: {
        enums: ['filled', 'hollow']
      },
      arrowWidth: {
        number: true,
        units: '%|px|em',
        implicitUnits: 'px',
        enums: ['match-line']
      },
      display: {
        enums: ['element', 'none']
      },
      visibility: {
        enums: ['hidden', 'visible']
      },
      zCompoundDepth: {
        enums: ['bottom', 'orphan', 'auto', 'top']
      },
      zIndexCompare: {
        enums: ['auto', 'manual']
      },
      valign: {
        enums: ['top', 'center', 'bottom']
      },
      halign: {
        enums: ['left', 'center', 'right']
      },
      justification: {
        enums: ['left', 'center', 'right', 'auto']
      },
      text: {
        string: true
      },
      data: {
        mapping: true,
        regex: data('data')
      },
      layoutData: {
        mapping: true,
        regex: data('layoutData')
      },
      scratch: {
        mapping: true,
        regex: data('scratch')
      },
      mapData: {
        mapping: true,
        regex: mapData('mapData')
      },
      mapLayoutData: {
        mapping: true,
        regex: mapData('mapLayoutData')
      },
      mapScratch: {
        mapping: true,
        regex: mapData('mapScratch')
      },
      fn: {
        mapping: true,
        fn: true
      },
      url: {
        regexes: urlRegexes,
        singleRegexMatchValue: true
      },
      urls: {
        regexes: urlRegexes,
        singleRegexMatchValue: true,
        multiple: true
      },
      propList: {
        propList: true
      },
      angle: {
        number: true,
        units: 'deg|rad',
        implicitUnits: 'rad'
      },
      textRotation: {
        number: true,
        units: 'deg|rad',
        implicitUnits: 'rad',
        enums: ['none', 'autorotate']
      },
      polygonPointList: {
        number: true,
        multiple: true,
        evenMultiple: true,
        min: -1,
        max: 1,
        unitless: true
      },
      edgeDistances: {
        enums: ['intersection', 'node-position', 'endpoints']
      },
      edgeEndpoint: {
        number: true,
        multiple: true,
        units: '%|px|em|deg|rad',
        implicitUnits: 'px',
        enums: ['inside-to-node', 'outside-to-node', 'outside-to-node-or-label', 'outside-to-line', 'outside-to-line-or-label'],
        singleEnum: true,
        validate: function validate(valArr, unitsArr) {
          switch (valArr.length) {
            case 2:
              // can be % or px only
              return unitsArr[0] !== 'deg' && unitsArr[0] !== 'rad' && unitsArr[1] !== 'deg' && unitsArr[1] !== 'rad';
            case 1:
              // can be enum, deg, or rad only
              return string(valArr[0]) || unitsArr[0] === 'deg' || unitsArr[0] === 'rad';
            default:
              return false;
          }
        }
      },
      easing: {
        regexes: ['^(spring)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$', '^(cubic-bezier)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$'],
        enums: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine', 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad', 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic', 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart', 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint', 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo', 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ']
      },
      gradientDirection: {
        enums: ['to-bottom', 'to-top', 'to-left', 'to-right', 'to-bottom-right', 'to-bottom-left', 'to-top-right', 'to-top-left', 'to-right-bottom', 'to-left-bottom', 'to-right-top', 'to-left-top' // different order
        ]
      },

      boundsExpansion: {
        number: true,
        multiple: true,
        min: 0,
        validate: function validate(valArr) {
          var length = valArr.length;
          return length === 1 || length === 2 || length === 4;
        }
      }
    };
    var diff = {
      zeroNonZero: function zeroNonZero(val1, val2) {
        if ((val1 == null || val2 == null) && val1 !== val2) {
          return true; // null cases could represent any value
        }
        if (val1 == 0 && val2 != 0) {
          return true;
        } else if (val1 != 0 && val2 == 0) {
          return true;
        } else {
          return false;
        }
      },
      any: function any(val1, val2) {
        return val1 != val2;
      },
      emptyNonEmpty: function emptyNonEmpty(str1, str2) {
        var empty1 = emptyString(str1);
        var empty2 = emptyString(str2);
        return empty1 && !empty2 || !empty1 && empty2;
      }
    };

    // define visual style properties
    //
    // - n.b. adding a new group of props may require updates to updateStyleHints()
    // - adding new props to an existing group gets handled automatically

    var t = styfn$2.types;
    var mainLabel = [{
      name: 'label',
      type: t.text,
      triggersBounds: diff.any,
      triggersZOrder: diff.emptyNonEmpty
    }, {
      name: 'text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }];
    var sourceLabel = [{
      name: 'source-label',
      type: t.text,
      triggersBounds: diff.any
    }, {
      name: 'source-text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'source-text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'source-text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'source-text-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var targetLabel = [{
      name: 'target-label',
      type: t.text,
      triggersBounds: diff.any
    }, {
      name: 'target-text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'target-text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'target-text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'target-text-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var labelDimensions = [{
      name: 'font-family',
      type: t.fontFamily,
      triggersBounds: diff.any
    }, {
      name: 'font-style',
      type: t.fontStyle,
      triggersBounds: diff.any
    }, {
      name: 'font-weight',
      type: t.fontWeight,
      triggersBounds: diff.any
    }, {
      name: 'font-size',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-transform',
      type: t.textTransform,
      triggersBounds: diff.any
    }, {
      name: 'text-wrap',
      type: t.textWrap,
      triggersBounds: diff.any
    }, {
      name: 'text-overflow-wrap',
      type: t.textOverflowWrap,
      triggersBounds: diff.any
    }, {
      name: 'text-max-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-outline-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'line-height',
      type: t.positiveNumber,
      triggersBounds: diff.any
    }];
    var commonLabel = [{
      name: 'text-valign',
      type: t.valign,
      triggersBounds: diff.any
    }, {
      name: 'text-halign',
      type: t.halign,
      triggersBounds: diff.any
    }, {
      name: 'color',
      type: t.color
    }, {
      name: 'text-outline-color',
      type: t.color
    }, {
      name: 'text-outline-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-background-color',
      type: t.color
    }, {
      name: 'text-background-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-background-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-border-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-border-color',
      type: t.color
    }, {
      name: 'text-border-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-border-style',
      type: t.borderStyle,
      triggersBounds: diff.any
    }, {
      name: 'text-background-shape',
      type: t.textBackgroundShape,
      triggersBounds: diff.any
    }, {
      name: 'text-justification',
      type: t.justification
    }];
    var behavior = [{
      name: 'events',
      type: t.bool,
      triggersZOrder: diff.any
    }, {
      name: 'text-events',
      type: t.bool,
      triggersZOrder: diff.any
    }];
    var visibility = [{
      name: 'display',
      type: t.display,
      triggersZOrder: diff.any,
      triggersBounds: diff.any,
      triggersBoundsOfConnectedEdges: true
    }, {
      name: 'visibility',
      type: t.visibility,
      triggersZOrder: diff.any
    }, {
      name: 'opacity',
      type: t.zeroOneNumber,
      triggersZOrder: diff.zeroNonZero
    }, {
      name: 'text-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'min-zoomed-font-size',
      type: t.size
    }, {
      name: 'z-compound-depth',
      type: t.zCompoundDepth,
      triggersZOrder: diff.any
    }, {
      name: 'z-index-compare',
      type: t.zIndexCompare,
      triggersZOrder: diff.any
    }, {
      name: 'z-index',
      type: t.number,
      triggersZOrder: diff.any
    }];
    var overlay = [{
      name: 'overlay-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'overlay-color',
      type: t.color
    }, {
      name: 'overlay-opacity',
      type: t.zeroOneNumber,
      triggersBounds: diff.zeroNonZero
    }, {
      name: 'overlay-shape',
      type: t.overlayShape,
      triggersBounds: diff.any
    }];
    var underlay = [{
      name: 'underlay-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'underlay-color',
      type: t.color
    }, {
      name: 'underlay-opacity',
      type: t.zeroOneNumber,
      triggersBounds: diff.zeroNonZero
    }, {
      name: 'underlay-shape',
      type: t.overlayShape,
      triggersBounds: diff.any
    }];
    var transition = [{
      name: 'transition-property',
      type: t.propList
    }, {
      name: 'transition-duration',
      type: t.time
    }, {
      name: 'transition-delay',
      type: t.time
    }, {
      name: 'transition-timing-function',
      type: t.easing
    }];
    var nodeSizeHashOverride = function nodeSizeHashOverride(ele, parsedProp) {
      if (parsedProp.value === 'label') {
        return -ele.poolIndex(); // no hash key hits is using label size (hitrate for perf probably low anyway)
      } else {
        return parsedProp.pfValue;
      }
    };
    var nodeBody = [{
      name: 'height',
      type: t.nodeSize,
      triggersBounds: diff.any,
      hashOverride: nodeSizeHashOverride
    }, {
      name: 'width',
      type: t.nodeSize,
      triggersBounds: diff.any,
      hashOverride: nodeSizeHashOverride
    }, {
      name: 'shape',
      type: t.nodeShape,
      triggersBounds: diff.any
    }, {
      name: 'shape-polygon-points',
      type: t.polygonPointList,
      triggersBounds: diff.any
    }, {
      name: 'background-color',
      type: t.color
    }, {
      name: 'background-fill',
      type: t.fill
    }, {
      name: 'background-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'background-blacken',
      type: t.nOneOneNumber
    }, {
      name: 'background-gradient-stop-colors',
      type: t.colors
    }, {
      name: 'background-gradient-stop-positions',
      type: t.percentages
    }, {
      name: 'background-gradient-direction',
      type: t.gradientDirection
    }, {
      name: 'padding',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'padding-relative-to',
      type: t.paddingRelativeTo,
      triggersBounds: diff.any
    }, {
      name: 'bounds-expansion',
      type: t.boundsExpansion,
      triggersBounds: diff.any
    }];
    var nodeBorder = [{
      name: 'border-color',
      type: t.color
    }, {
      name: 'border-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'border-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'border-style',
      type: t.borderStyle
    }];
    var nodeOutline = [{
      name: 'outline-color',
      type: t.color
    }, {
      name: 'outline-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'outline-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'outline-style',
      type: t.borderStyle
    }, {
      name: 'outline-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var backgroundImage = [{
      name: 'background-image',
      type: t.urls
    }, {
      name: 'background-image-crossorigin',
      type: t.bgCrossOrigin
    }, {
      name: 'background-image-opacity',
      type: t.zeroOneNumbers
    }, {
      name: 'background-image-containment',
      type: t.bgContainment
    }, {
      name: 'background-image-smoothing',
      type: t.bools
    }, {
      name: 'background-position-x',
      type: t.bgPos
    }, {
      name: 'background-position-y',
      type: t.bgPos
    }, {
      name: 'background-width-relative-to',
      type: t.bgRelativeTo
    }, {
      name: 'background-height-relative-to',
      type: t.bgRelativeTo
    }, {
      name: 'background-repeat',
      type: t.bgRepeat
    }, {
      name: 'background-fit',
      type: t.bgFit
    }, {
      name: 'background-clip',
      type: t.bgClip
    }, {
      name: 'background-width',
      type: t.bgWH
    }, {
      name: 'background-height',
      type: t.bgWH
    }, {
      name: 'background-offset-x',
      type: t.bgPos
    }, {
      name: 'background-offset-y',
      type: t.bgPos
    }];
    var compound = [{
      name: 'position',
      type: t.position,
      triggersBounds: diff.any
    }, {
      name: 'compound-sizing-wrt-labels',
      type: t.compoundIncludeLabels,
      triggersBounds: diff.any
    }, {
      name: 'min-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'min-width-bias-left',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-width-bias-right',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-height',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'min-height-bias-top',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-height-bias-bottom',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }];
    var edgeLine = [{
      name: 'line-style',
      type: t.lineStyle
    }, {
      name: 'line-color',
      type: t.color
    }, {
      name: 'line-fill',
      type: t.fill
    }, {
      name: 'line-cap',
      type: t.lineCap
    }, {
      name: 'line-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'line-dash-pattern',
      type: t.numbers
    }, {
      name: 'line-dash-offset',
      type: t.number
    }, {
      name: 'line-gradient-stop-colors',
      type: t.colors
    }, {
      name: 'line-gradient-stop-positions',
      type: t.percentages
    }, {
      name: 'curve-style',
      type: t.curveStyle,
      triggersBounds: diff.any,
      triggersBoundsOfParallelBeziers: true
    }, {
      name: 'haystack-radius',
      type: t.zeroOneNumber,
      triggersBounds: diff.any
    }, {
      name: 'source-endpoint',
      type: t.edgeEndpoint,
      triggersBounds: diff.any
    }, {
      name: 'target-endpoint',
      type: t.edgeEndpoint,
      triggersBounds: diff.any
    }, {
      name: 'control-point-step-size',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'control-point-distances',
      type: t.bidirectionalSizes,
      triggersBounds: diff.any
    }, {
      name: 'control-point-weights',
      type: t.numbers,
      triggersBounds: diff.any
    }, {
      name: 'segment-distances',
      type: t.bidirectionalSizes,
      triggersBounds: diff.any
    }, {
      name: 'segment-weights',
      type: t.numbers,
      triggersBounds: diff.any
    }, {
      name: 'taxi-turn',
      type: t.bidirectionalSizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'taxi-turn-min-distance',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'taxi-direction',
      type: t.axisDirection,
      triggersBounds: diff.any
    }, {
      name: 'edge-distances',
      type: t.edgeDistances,
      triggersBounds: diff.any
    }, {
      name: 'arrow-scale',
      type: t.positiveNumber,
      triggersBounds: diff.any
    }, {
      name: 'loop-direction',
      type: t.angle,
      triggersBounds: diff.any
    }, {
      name: 'loop-sweep',
      type: t.angle,
      triggersBounds: diff.any
    }, {
      name: 'source-distance-from-node',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'target-distance-from-node',
      type: t.size,
      triggersBounds: diff.any
    }];
    var ghost = [{
      name: 'ghost',
      type: t.bool,
      triggersBounds: diff.any
    }, {
      name: 'ghost-offset-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'ghost-offset-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'ghost-opacity',
      type: t.zeroOneNumber
    }];
    var core = [{
      name: 'selection-box-color',
      type: t.color
    }, {
      name: 'selection-box-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'selection-box-border-color',
      type: t.color
    }, {
      name: 'selection-box-border-width',
      type: t.size
    }, {
      name: 'active-bg-color',
      type: t.color
    }, {
      name: 'active-bg-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'active-bg-size',
      type: t.size
    }, {
      name: 'outside-texture-bg-color',
      type: t.color
    }, {
      name: 'outside-texture-bg-opacity',
      type: t.zeroOneNumber
    }];

    // pie backgrounds for nodes
    var pie = [];
    styfn$2.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use)
    pie.push({
      name: 'pie-size',
      type: t.sizeMaybePercent
    });
    for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {
      pie.push({
        name: 'pie-' + i + '-background-color',
        type: t.color
      });
      pie.push({
        name: 'pie-' + i + '-background-size',
        type: t.percent
      });
      pie.push({
        name: 'pie-' + i + '-background-opacity',
        type: t.zeroOneNumber
      });
    }

    // edge arrows
    var edgeArrow = [];
    var arrowPrefixes = styfn$2.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target'];
    [{
      name: 'arrow-shape',
      type: t.arrowShape,
      triggersBounds: diff.any
    }, {
      name: 'arrow-color',
      type: t.color
    }, {
      name: 'arrow-fill',
      type: t.arrowFill
    }, {
      name: 'arrow-width',
      type: t.arrowWidth
    }].forEach(function (prop) {
      arrowPrefixes.forEach(function (prefix) {
        var name = prefix + '-' + prop.name;
        var type = prop.type,
          triggersBounds = prop.triggersBounds;
        edgeArrow.push({
          name: name,
          type: type,
          triggersBounds: triggersBounds
        });
      });
    }, {});
    var props = styfn$2.properties = [].concat(behavior, transition, visibility, overlay, underlay, ghost, commonLabel, labelDimensions, mainLabel, sourceLabel, targetLabel, nodeBody, nodeBorder, nodeOutline, backgroundImage, pie, compound, edgeLine, edgeArrow, core);
    var propGroups = styfn$2.propertyGroups = {
      // common to all eles
      behavior: behavior,
      transition: transition,
      visibility: visibility,
      overlay: overlay,
      underlay: underlay,
      ghost: ghost,
      // labels
      commonLabel: commonLabel,
      labelDimensions: labelDimensions,
      mainLabel: mainLabel,
      sourceLabel: sourceLabel,
      targetLabel: targetLabel,
      // node props
      nodeBody: nodeBody,
      nodeBorder: nodeBorder,
      nodeOutline: nodeOutline,
      backgroundImage: backgroundImage,
      pie: pie,
      compound: compound,
      // edge props
      edgeLine: edgeLine,
      edgeArrow: edgeArrow,
      core: core
    };
    var propGroupNames = styfn$2.propertyGroupNames = {};
    var propGroupKeys = styfn$2.propertyGroupKeys = Object.keys(propGroups);
    propGroupKeys.forEach(function (key) {
      propGroupNames[key] = propGroups[key].map(function (prop) {
        return prop.name;
      });
      propGroups[key].forEach(function (prop) {
        return prop.groupKey = key;
      });
    });

    // define aliases
    var aliases = styfn$2.aliases = [{
      name: 'content',
      pointsTo: 'label'
    }, {
      name: 'control-point-distance',
      pointsTo: 'control-point-distances'
    }, {
      name: 'control-point-weight',
      pointsTo: 'control-point-weights'
    }, {
      name: 'edge-text-rotation',
      pointsTo: 'text-rotation'
    }, {
      name: 'padding-left',
      pointsTo: 'padding'
    }, {
      name: 'padding-right',
      pointsTo: 'padding'
    }, {
      name: 'padding-top',
      pointsTo: 'padding'
    }, {
      name: 'padding-bottom',
      pointsTo: 'padding'
    }];

    // list of property names
    styfn$2.propertyNames = props.map(function (p) {
      return p.name;
    });

    // allow access of properties by name ( e.g. style.properties.height )
    for (var _i = 0; _i < props.length; _i++) {
      var prop = props[_i];
      props[prop.name] = prop; // allow lookup by name
    }

    // map aliases
    for (var _i2 = 0; _i2 < aliases.length; _i2++) {
      var alias = aliases[_i2];
      var pointsToProp = props[alias.pointsTo];
      var aliasProp = {
        name: alias.name,
        alias: true,
        pointsTo: pointsToProp
      };

      // add alias prop for parsing
      props.push(aliasProp);
      props[alias.name] = aliasProp; // allow lookup by name
    }
  })();

  styfn$2.getDefaultProperty = function (name) {
    return this.getDefaultProperties()[name];
  };
  styfn$2.getDefaultProperties = function () {
    var _p = this._private;
    if (_p.defaultProperties != null) {
      return _p.defaultProperties;
    }
    var rawProps = extend({
      // core props
      'selection-box-color': '#ddd',
      'selection-box-opacity': 0.65,
      'selection-box-border-color': '#aaa',
      'selection-box-border-width': 1,
      'active-bg-color': 'black',
      'active-bg-opacity': 0.15,
      'active-bg-size': 30,
      'outside-texture-bg-color': '#000',
      'outside-texture-bg-opacity': 0.125,
      // common node/edge props
      'events': 'yes',
      'text-events': 'no',
      'text-valign': 'top',
      'text-halign': 'center',
      'text-justification': 'auto',
      'line-height': 1,
      'color': '#000',
      'text-outline-color': '#000',
      'text-outline-width': 0,
      'text-outline-opacity': 1,
      'text-opacity': 1,
      'text-decoration': 'none',
      'text-transform': 'none',
      'text-wrap': 'none',
      'text-overflow-wrap': 'whitespace',
      'text-max-width': 9999,
      'text-background-color': '#000',
      'text-background-opacity': 0,
      'text-background-shape': 'rectangle',
      'text-background-padding': 0,
      'text-border-opacity': 0,
      'text-border-width': 0,
      'text-border-style': 'solid',
      'text-border-color': '#000',
      'font-family': 'Helvetica Neue, Helvetica, sans-serif',
      'font-style': 'normal',
      'font-weight': 'normal',
      'font-size': 16,
      'min-zoomed-font-size': 0,
      'text-rotation': 'none',
      'source-text-rotation': 'none',
      'target-text-rotation': 'none',
      'visibility': 'visible',
      'display': 'element',
      'opacity': 1,
      'z-compound-depth': 'auto',
      'z-index-compare': 'auto',
      'z-index': 0,
      'label': '',
      'text-margin-x': 0,
      'text-margin-y': 0,
      'source-label': '',
      'source-text-offset': 0,
      'source-text-margin-x': 0,
      'source-text-margin-y': 0,
      'target-label': '',
      'target-text-offset': 0,
      'target-text-margin-x': 0,
      'target-text-margin-y': 0,
      'overlay-opacity': 0,
      'overlay-color': '#000',
      'overlay-padding': 10,
      'overlay-shape': 'round-rectangle',
      'underlay-opacity': 0,
      'underlay-color': '#000',
      'underlay-padding': 10,
      'underlay-shape': 'round-rectangle',
      'transition-property': 'none',
      'transition-duration': 0,
      'transition-delay': 0,
      'transition-timing-function': 'linear',
      // node props
      'background-blacken': 0,
      'background-color': '#999',
      'background-fill': 'solid',
      'background-opacity': 1,
      'background-image': 'none',
      'background-image-crossorigin': 'anonymous',
      'background-image-opacity': 1,
      'background-image-containment': 'inside',
      'background-image-smoothing': 'yes',
      'background-position-x': '50%',
      'background-position-y': '50%',
      'background-offset-x': 0,
      'background-offset-y': 0,
      'background-width-relative-to': 'include-padding',
      'background-height-relative-to': 'include-padding',
      'background-repeat': 'no-repeat',
      'background-fit': 'none',
      'background-clip': 'node',
      'background-width': 'auto',
      'background-height': 'auto',
      'border-color': '#000',
      'border-opacity': 1,
      'border-width': 0,
      'border-style': 'solid',
      'outline-color': '#999',
      'outline-opacity': 1,
      'outline-width': 0,
      'outline-offset': 0,
      'outline-style': 'solid',
      'height': 30,
      'width': 30,
      'shape': 'ellipse',
      'shape-polygon-points': '-1, -1,   1, -1,   1, 1,   -1, 1',
      'bounds-expansion': 0,
      // node gradient
      'background-gradient-direction': 'to-bottom',
      'background-gradient-stop-colors': '#999',
      'background-gradient-stop-positions': '0%',
      // ghost props
      'ghost': 'no',
      'ghost-offset-y': 0,
      'ghost-offset-x': 0,
      'ghost-opacity': 0,
      // compound props
      'padding': 0,
      'padding-relative-to': 'width',
      'position': 'origin',
      'compound-sizing-wrt-labels': 'include',
      'min-width': 0,
      'min-width-bias-left': 0,
      'min-width-bias-right': 0,
      'min-height': 0,
      'min-height-bias-top': 0,
      'min-height-bias-bottom': 0
    }, {
      // node pie bg
      'pie-size': '100%'
    }, [{
      name: 'pie-{{i}}-background-color',
      value: 'black'
    }, {
      name: 'pie-{{i}}-background-size',
      value: '0%'
    }, {
      name: 'pie-{{i}}-background-opacity',
      value: 1
    }].reduce(function (css, prop) {
      for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {
        var name = prop.name.replace('{{i}}', i);
        var val = prop.value;
        css[name] = val;
      }
      return css;
    }, {}), {
      // edge props
      'line-style': 'solid',
      'line-color': '#999',
      'line-fill': 'solid',
      'line-cap': 'butt',
      'line-opacity': 1,
      'line-gradient-stop-colors': '#999',
      'line-gradient-stop-positions': '0%',
      'control-point-step-size': 40,
      'control-point-weights': 0.5,
      'segment-weights': 0.5,
      'segment-distances': 20,
      'taxi-turn': '50%',
      'taxi-turn-min-distance': 10,
      'taxi-direction': 'auto',
      'edge-distances': 'intersection',
      'curve-style': 'haystack',
      'haystack-radius': 0,
      'arrow-scale': 1,
      'loop-direction': '-45deg',
      'loop-sweep': '-90deg',
      'source-distance-from-node': 0,
      'target-distance-from-node': 0,
      'source-endpoint': 'outside-to-node',
      'target-endpoint': 'outside-to-node',
      'line-dash-pattern': [6, 3],
      'line-dash-offset': 0
    }, [{
      name: 'arrow-shape',
      value: 'none'
    }, {
      name: 'arrow-color',
      value: '#999'
    }, {
      name: 'arrow-fill',
      value: 'filled'
    }, {
      name: 'arrow-width',
      value: 1
    }].reduce(function (css, prop) {
      styfn$2.arrowPrefixes.forEach(function (prefix) {
        var name = prefix + '-' + prop.name;
        var val = prop.value;
        css[name] = val;
      });
      return css;
    }, {}));
    var parsedProps = {};
    for (var i = 0; i < this.properties.length; i++) {
      var prop = this.properties[i];
      if (prop.pointsTo) {
        continue;
      }
      var name = prop.name;
      var val = rawProps[name];
      var parsedProp = this.parse(name, val);
      parsedProps[name] = parsedProp;
    }
    _p.defaultProperties = parsedProps;
    return _p.defaultProperties;
  };
  styfn$2.addDefaultStylesheet = function () {
    this.selector(':parent').css({
      'shape': 'rectangle',
      'padding': 10,
      'background-color': '#eee',
      'border-color': '#ccc',
      'border-width': 1
    }).selector('edge').css({
      'width': 3
    }).selector(':loop').css({
      'curve-style': 'bezier'
    }).selector('edge:compound').css({
      'curve-style': 'bezier',
      'source-endpoint': 'outside-to-line',
      'target-endpoint': 'outside-to-line'
    }).selector(':selected').css({
      'background-color': '#0169D9',
      'line-color': '#0169D9',
      'source-arrow-color': '#0169D9',
      'target-arrow-color': '#0169D9',
      'mid-source-arrow-color': '#0169D9',
      'mid-target-arrow-color': '#0169D9'
    }).selector(':parent:selected').css({
      'background-color': '#CCE1F9',
      'border-color': '#aec8e5'
    }).selector(':active').css({
      'overlay-color': 'black',
      'overlay-padding': 10,
      'overlay-opacity': 0.25
    });
    this.defaultLength = this.length;
  };

  var styfn$1 = {};

  // a caching layer for property parsing
  styfn$1.parse = function (name, value, propIsBypass, propIsFlat) {
    var self = this;

    // function values can't be cached in all cases, and there isn't much benefit of caching them anyway
    if (fn$6(value)) {
      return self.parseImplWarn(name, value, propIsBypass, propIsFlat);
    }
    var flatKey = propIsFlat === 'mapping' || propIsFlat === true || propIsFlat === false || propIsFlat == null ? 'dontcare' : propIsFlat;
    var bypassKey = propIsBypass ? 't' : 'f';
    var valueKey = '' + value;
    var argHash = hashStrings(name, valueKey, bypassKey, flatKey);
    var propCache = self.propCache = self.propCache || [];
    var ret;
    if (!(ret = propCache[argHash])) {
      ret = propCache[argHash] = self.parseImplWarn(name, value, propIsBypass, propIsFlat);
    }

    // - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden
    // - mappings can't be shared b/c mappings are per-element
    if (propIsBypass || propIsFlat === 'mapping') {
      // need a copy since props are mutated later in their lifecycles
      ret = copy(ret);
      if (ret) {
        ret.value = copy(ret.value); // because it could be an array, e.g. colour
      }
    }

    return ret;
  };
  styfn$1.parseImplWarn = function (name, value, propIsBypass, propIsFlat) {
    var prop = this.parseImpl(name, value, propIsBypass, propIsFlat);
    if (!prop && value != null) {
      warn("The style property `".concat(name, ": ").concat(value, "` is invalid"));
    }
    if (prop && (prop.name === 'width' || prop.name === 'height') && value === 'label') {
      warn('The style value of `label` is deprecated for `' + prop.name + '`');
    }
    return prop;
  };

  // parse a property; return null on invalid; return parsed property otherwise
  // fields :
  // - name : the name of the property
  // - value : the parsed, native-typed value of the property
  // - strValue : a string value that represents the property value in valid css
  // - bypass : true iff the property is a bypass property
  styfn$1.parseImpl = function (name, value, propIsBypass, propIsFlat) {
    var self = this;
    name = camel2dash(name); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')

    var property = self.properties[name];
    var passedValue = value;
    var types = self.types;
    if (!property) {
      return null;
    } // return null on property of unknown name
    if (value === undefined) {
      return null;
    } // can't assign undefined

    // the property may be an alias
    if (property.alias) {
      property = property.pointsTo;
      name = property.name;
    }
    var valueIsString = string(value);
    if (valueIsString) {
      // trim the value to make parsing easier
      value = value.trim();
    }
    var type = property.type;
    if (!type) {
      return null;
    } // no type, no luck

    // check if bypass is null or empty string (i.e. indication to delete bypass property)
    if (propIsBypass && (value === '' || value === null)) {
      return {
        name: name,
        value: value,
        bypass: true,
        deleteBypass: true
      };
    }

    // check if value is a function used as a mapper
    if (fn$6(value)) {
      return {
        name: name,
        value: value,
        strValue: 'fn',
        mapped: types.fn,
        bypass: propIsBypass
      };
    }

    // check if value is mapped
    var data, mapData;
    if (!valueIsString || propIsFlat || value.length < 7 || value[1] !== 'a') ; else if (value.length >= 7 && value[0] === 'd' && (data = new RegExp(types.data.regex).exec(value))) {
      if (propIsBypass) {
        return false;
      } // mappers not allowed in bypass

      var mapped = types.data;
      return {
        name: name,
        value: data,
        strValue: '' + value,
        mapped: mapped,
        field: data[1],
        bypass: propIsBypass
      };
    } else if (value.length >= 10 && value[0] === 'm' && (mapData = new RegExp(types.mapData.regex).exec(value))) {
      if (propIsBypass) {
        return false;
      } // mappers not allowed in bypass
      if (type.multiple) {
        return false;
      } // impossible to map to num

      var _mapped = types.mapData;

      // we can map only if the type is a colour or a number
      if (!(type.color || type.number)) {
        return false;
      }
      var valueMin = this.parse(name, mapData[4]); // parse to validate
      if (!valueMin || valueMin.mapped) {
        return false;
      } // can't be invalid or mapped

      var valueMax = this.parse(name, mapData[5]); // parse to validate
      if (!valueMax || valueMax.mapped) {
        return false;
      } // can't be invalid or mapped

      // check if valueMin and valueMax are the same
      if (valueMin.pfValue === valueMax.pfValue || valueMin.strValue === valueMax.strValue) {
        warn('`' + name + ': ' + value + '` is not a valid mapper because the output range is zero; converting to `' + name + ': ' + valueMin.strValue + '`');
        return this.parse(name, valueMin.strValue); // can't make much of a mapper without a range
      } else if (type.color) {
        var c1 = valueMin.value;
        var c2 = valueMax.value;
        var same = c1[0] === c2[0] // red
        && c1[1] === c2[1] // green
        && c1[2] === c2[2] // blue
        && (
        // optional alpha
        c1[3] === c2[3] // same alpha outright
        || (c1[3] == null || c1[3] === 1 // full opacity for colour 1?
        ) && (c2[3] == null || c2[3] === 1) // full opacity for colour 2?
        );

        if (same) {
          return false;
        } // can't make a mapper without a range
      }

      return {
        name: name,
        value: mapData,
        strValue: '' + value,
        mapped: _mapped,
        field: mapData[1],
        fieldMin: parseFloat(mapData[2]),
        // min & max are numeric
        fieldMax: parseFloat(mapData[3]),
        valueMin: valueMin.value,
        valueMax: valueMax.value,
        bypass: propIsBypass
      };
    }
    if (type.multiple && propIsFlat !== 'multiple') {
      var vals;
      if (valueIsString) {
        vals = value.split(/\s+/);
      } else if (array(value)) {
        vals = value;
      } else {
        vals = [value];
      }
      if (type.evenMultiple && vals.length % 2 !== 0) {
        return null;
      }
      var valArr = [];
      var unitsArr = [];
      var pfValArr = [];
      var strVal = '';
      var hasEnum = false;
      for (var i = 0; i < vals.length; i++) {
        var p = self.parse(name, vals[i], propIsBypass, 'multiple');
        hasEnum = hasEnum || string(p.value);
        valArr.push(p.value);
        pfValArr.push(p.pfValue != null ? p.pfValue : p.value);
        unitsArr.push(p.units);
        strVal += (i > 0 ? ' ' : '') + p.strValue;
      }
      if (type.validate && !type.validate(valArr, unitsArr)) {
        return null;
      }
      if (type.singleEnum && hasEnum) {
        if (valArr.length === 1 && string(valArr[0])) {
          return {
            name: name,
            value: valArr[0],
            strValue: valArr[0],
            bypass: propIsBypass
          };
        } else {
          return null;
        }
      }
      return {
        name: name,
        value: valArr,
        pfValue: pfValArr,
        strValue: strVal,
        bypass: propIsBypass,
        units: unitsArr
      };
    }

    // several types also allow enums
    var checkEnums = function checkEnums() {
      for (var _i = 0; _i < type.enums.length; _i++) {
        var en = type.enums[_i];
        if (en === value) {
          return {
            name: name,
            value: value,
            strValue: '' + value,
            bypass: propIsBypass
          };
        }
      }
      return null;
    };

    // check the type and return the appropriate object
    if (type.number) {
      var units;
      var implicitUnits = 'px'; // not set => px

      if (type.units) {
        // use specified units if set
        units = type.units;
      }
      if (type.implicitUnits) {
        implicitUnits = type.implicitUnits;
      }
      if (!type.unitless) {
        if (valueIsString) {
          var unitsRegex = 'px|em' + (type.allowPercent ? '|\\%' : '');
          if (units) {
            unitsRegex = units;
          } // only allow explicit units if so set
          var match = value.match('^(' + number + ')(' + unitsRegex + ')?' + '$');
          if (match) {
            value = match[1];
            units = match[2] || implicitUnits;
          }
        } else if (!units || type.implicitUnits) {
          units = implicitUnits; // implicitly px if unspecified
        }
      }

      value = parseFloat(value);

      // if not a number and enums not allowed, then the value is invalid
      if (isNaN(value) && type.enums === undefined) {
        return null;
      }

      // check if this number type also accepts special keywords in place of numbers
      // (i.e. `left`, `auto`, etc)
      if (isNaN(value) && type.enums !== undefined) {
        value = passedValue;
        return checkEnums();
      }

      // check if value must be an integer
      if (type.integer && !integer(value)) {
        return null;
      }

      // check value is within range
      if (type.min !== undefined && (value < type.min || type.strictMin && value === type.min) || type.max !== undefined && (value > type.max || type.strictMax && value === type.max)) {
        return null;
      }
      var ret = {
        name: name,
        value: value,
        strValue: '' + value + (units ? units : ''),
        units: units,
        bypass: propIsBypass
      };

      // normalise value in pixels
      if (type.unitless || units !== 'px' && units !== 'em') {
        ret.pfValue = value;
      } else {
        ret.pfValue = units === 'px' || !units ? value : this.getEmSizeInPixels() * value;
      }

      // normalise value in ms
      if (units === 'ms' || units === 's') {
        ret.pfValue = units === 'ms' ? value : 1000 * value;
      }

      // normalise value in rad
      if (units === 'deg' || units === 'rad') {
        ret.pfValue = units === 'rad' ? value : deg2rad(value);
      }

      // normalize value in %
      if (units === '%') {
        ret.pfValue = value / 100;
      }
      return ret;
    } else if (type.propList) {
      var props = [];
      var propsStr = '' + value;
      if (propsStr === 'none') ; else {
        // go over each prop

        var propsSplit = propsStr.split(/\s*,\s*|\s+/);
        for (var _i2 = 0; _i2 < propsSplit.length; _i2++) {
          var propName = propsSplit[_i2].trim();
          if (self.properties[propName]) {
            props.push(propName);
          } else {
            warn('`' + propName + '` is not a valid property name');
          }
        }
        if (props.length === 0) {
          return null;
        }
      }
      return {
        name: name,
        value: props,
        strValue: props.length === 0 ? 'none' : props.join(' '),
        bypass: propIsBypass
      };
    } else if (type.color) {
      var tuple = color2tuple(value);
      if (!tuple) {
        return null;
      }
      return {
        name: name,
        value: tuple,
        pfValue: tuple,
        strValue: 'rgb(' + tuple[0] + ',' + tuple[1] + ',' + tuple[2] + ')',
        // n.b. no spaces b/c of multiple support
        bypass: propIsBypass
      };
    } else if (type.regex || type.regexes) {
      // first check enums
      if (type.enums) {
        var enumProp = checkEnums();
        if (enumProp) {
          return enumProp;
        }
      }
      var regexes = type.regexes ? type.regexes : [type.regex];
      for (var _i3 = 0; _i3 < regexes.length; _i3++) {
        var regex = new RegExp(regexes[_i3]); // make a regex from the type string
        var m = regex.exec(value);
        if (m) {
          // regex matches
          return {
            name: name,
            value: type.singleRegexMatchValue ? m[1] : m,
            strValue: '' + value,
            bypass: propIsBypass
          };
        }
      }
      return null; // didn't match any
    } else if (type.string) {
      // just return
      return {
        name: name,
        value: '' + value,
        strValue: '' + value,
        bypass: propIsBypass
      };
    } else if (type.enums) {
      // check enums last because it's a combo type in others
      return checkEnums();
    } else {
      return null; // not a type we can handle
    }
  };

  var Style = function Style(cy) {
    if (!(this instanceof Style)) {
      return new Style(cy);
    }
    if (!core(cy)) {
      error('A style must have a core reference');
      return;
    }
    this._private = {
      cy: cy,
      coreStyle: {}
    };
    this.length = 0;
    this.resetToDefault();
  };
  var styfn = Style.prototype;
  styfn.instanceString = function () {
    return 'style';
  };

  // remove all contexts
  styfn.clear = function () {
    var _p = this._private;
    var cy = _p.cy;
    var eles = cy.elements();
    for (var i = 0; i < this.length; i++) {
      this[i] = undefined;
    }
    this.length = 0;
    _p.contextStyles = {};
    _p.propDiffs = {};
    this.cleanElements(eles, true);
    eles.forEach(function (ele) {
      var ele_p = ele[0]._private;
      ele_p.styleDirty = true;
      ele_p.appliedInitStyle = false;
    });
    return this; // chaining
  };

  styfn.resetToDefault = function () {
    this.clear();
    this.addDefaultStylesheet();
    return this;
  };

  // builds a style object for the 'core' selector
  styfn.core = function (propName) {
    return this._private.coreStyle[propName] || this.getDefaultProperty(propName);
  };

  // create a new context from the specified selector string and switch to that context
  styfn.selector = function (selectorStr) {
    // 'core' is a special case and does not need a selector
    var selector = selectorStr === 'core' ? null : new Selector(selectorStr);
    var i = this.length++; // new context means new index
    this[i] = {
      selector: selector,
      properties: [],
      mappedProperties: [],
      index: i
    };
    return this; // chaining
  };

  // add one or many css rules to the current context
  styfn.css = function () {
    var self = this;
    var args = arguments;
    if (args.length === 1) {
      var map = args[0];
      for (var i = 0; i < self.properties.length; i++) {
        var prop = self.properties[i];
        var mapVal = map[prop.name];
        if (mapVal === undefined) {
          mapVal = map[dash2camel(prop.name)];
        }
        if (mapVal !== undefined) {
          this.cssRule(prop.name, mapVal);
        }
      }
    } else if (args.length === 2) {
      this.cssRule(args[0], args[1]);
    }

    // do nothing if args are invalid

    return this; // chaining
  };

  styfn.style = styfn.css;

  // add a single css rule to the current context
  styfn.cssRule = function (name, value) {
    // name-value pair
    var property = this.parse(name, value);

    // add property to current context if valid
    if (property) {
      var i = this.length - 1;
      this[i].properties.push(property);
      this[i].properties[property.name] = property; // allow access by name as well

      if (property.name.match(/pie-(\d+)-background-size/) && property.value) {
        this._private.hasPie = true;
      }
      if (property.mapped) {
        this[i].mappedProperties.push(property);
      }

      // add to core style if necessary
      var currentSelectorIsCore = !this[i].selector;
      if (currentSelectorIsCore) {
        this._private.coreStyle[property.name] = property;
      }
    }
    return this; // chaining
  };

  styfn.append = function (style) {
    if (stylesheet(style)) {
      style.appendToStyle(this);
    } else if (array(style)) {
      this.appendFromJson(style);
    } else if (string(style)) {
      this.appendFromString(style);
    } // you probably wouldn't want to append a Style, since you'd duplicate the default parts

    return this;
  };

  // static function
  Style.fromJson = function (cy, json) {
    var style = new Style(cy);
    style.fromJson(json);
    return style;
  };
  Style.fromString = function (cy, string) {
    return new Style(cy).fromString(string);
  };
  [styfn$8, styfn$7, styfn$6, styfn$5, styfn$4, styfn$3, styfn$2, styfn$1].forEach(function (props) {
    extend(styfn, props);
  });
  Style.types = styfn.types;
  Style.properties = styfn.properties;
  Style.propertyGroups = styfn.propertyGroups;
  Style.propertyGroupNames = styfn.propertyGroupNames;
  Style.propertyGroupKeys = styfn.propertyGroupKeys;

  var corefn$2 = {
    style: function style(newStyle) {
      if (newStyle) {
        var s = this.setStyle(newStyle);
        s.update();
      }
      return this._private.style;
    },
    setStyle: function setStyle(style) {
      var _p = this._private;
      if (stylesheet(style)) {
        _p.style = style.generateStyle(this);
      } else if (array(style)) {
        _p.style = Style.fromJson(this, style);
      } else if (string(style)) {
        _p.style = Style.fromString(this, style);
      } else {
        _p.style = Style(this);
      }
      return _p.style;
    },
    // e.g. cy.data() changed => recalc ele mappers
    updateStyle: function updateStyle() {
      this.mutableElements().updateStyle(); // just send to all eles
    }
  };

  var defaultSelectionType = 'single';
  var corefn$1 = {
    autolock: function autolock(bool) {
      if (bool !== undefined) {
        this._private.autolock = bool ? true : false;
      } else {
        return this._private.autolock;
      }
      return this; // chaining
    },

    autoungrabify: function autoungrabify(bool) {
      if (bool !== undefined) {
        this._private.autoungrabify = bool ? true : false;
      } else {
        return this._private.autoungrabify;
      }
      return this; // chaining
    },

    autounselectify: function autounselectify(bool) {
      if (bool !== undefined) {
        this._private.autounselectify = bool ? true : false;
      } else {
        return this._private.autounselectify;
      }
      return this; // chaining
    },

    selectionType: function selectionType(selType) {
      var _p = this._private;
      if (_p.selectionType == null) {
        _p.selectionType = defaultSelectionType;
      }
      if (selType !== undefined) {
        if (selType === 'additive' || selType === 'single') {
          _p.selectionType = selType;
        }
      } else {
        return _p.selectionType;
      }
      return this;
    },
    panningEnabled: function panningEnabled(bool) {
      if (bool !== undefined) {
        this._private.panningEnabled = bool ? true : false;
      } else {
        return this._private.panningEnabled;
      }
      return this; // chaining
    },

    userPanningEnabled: function userPanningEnabled(bool) {
      if (bool !== undefined) {
        this._private.userPanningEnabled = bool ? true : false;
      } else {
        return this._private.userPanningEnabled;
      }
      return this; // chaining
    },

    zoomingEnabled: function zoomingEnabled(bool) {
      if (bool !== undefined) {
        this._private.zoomingEnabled = bool ? true : false;
      } else {
        return this._private.zoomingEnabled;
      }
      return this; // chaining
    },

    userZoomingEnabled: function userZoomingEnabled(bool) {
      if (bool !== undefined) {
        this._private.userZoomingEnabled = bool ? true : false;
      } else {
        return this._private.userZoomingEnabled;
      }
      return this; // chaining
    },

    boxSelectionEnabled: function boxSelectionEnabled(bool) {
      if (bool !== undefined) {
        this._private.boxSelectionEnabled = bool ? true : false;
      } else {
        return this._private.boxSelectionEnabled;
      }
      return this; // chaining
    },

    pan: function pan() {
      var args = arguments;
      var pan = this._private.pan;
      var dim, val, dims, x, y;
      switch (args.length) {
        case 0:
          // .pan()
          return pan;
        case 1:
          if (string(args[0])) {
            // .pan('x')
            dim = args[0];
            return pan[dim];
          } else if (plainObject(args[0])) {
            // .pan({ x: 0, y: 100 })
            if (!this._private.panningEnabled) {
              return this;
            }
            dims = args[0];
            x = dims.x;
            y = dims.y;
            if (number$1(x)) {
              pan.x = x;
            }
            if (number$1(y)) {
              pan.y = y;
            }
            this.emit('pan viewport');
          }
          break;
        case 2:
          // .pan('x', 100)
          if (!this._private.panningEnabled) {
            return this;
          }
          dim = args[0];
          val = args[1];
          if ((dim === 'x' || dim === 'y') && number$1(val)) {
            pan[dim] = val;
          }
          this.emit('pan viewport');
          break;
        // invalid
      }

      this.notify('viewport');
      return this; // chaining
    },

    panBy: function panBy(arg0, arg1) {
      var args = arguments;
      var pan = this._private.pan;
      var dim, val, dims, x, y;
      if (!this._private.panningEnabled) {
        return this;
      }
      switch (args.length) {
        case 1:
          if (plainObject(arg0)) {
            // .panBy({ x: 0, y: 100 })
            dims = args[0];
            x = dims.x;
            y = dims.y;
            if (number$1(x)) {
              pan.x += x;
            }
            if (number$1(y)) {
              pan.y += y;
            }
            this.emit('pan viewport');
          }
          break;
        case 2:
          // .panBy('x', 100)
          dim = arg0;
          val = arg1;
          if ((dim === 'x' || dim === 'y') && number$1(val)) {
            pan[dim] += val;
          }
          this.emit('pan viewport');
          break;
        // invalid
      }

      this.notify('viewport');
      return this; // chaining
    },

    fit: function fit(elements, padding) {
      var viewportState = this.getFitViewport(elements, padding);
      if (viewportState) {
        var _p = this._private;
        _p.zoom = viewportState.zoom;
        _p.pan = viewportState.pan;
        this.emit('pan zoom viewport');
        this.notify('viewport');
      }
      return this; // chaining
    },

    getFitViewport: function getFitViewport(elements, padding) {
      if (number$1(elements) && padding === undefined) {
        // elements is optional
        padding = elements;
        elements = undefined;
      }
      if (!this._private.panningEnabled || !this._private.zoomingEnabled) {
        return;
      }
      var bb;
      if (string(elements)) {
        var sel = elements;
        elements = this.$(sel);
      } else if (boundingBox(elements)) {
        // assume bb
        var bbe = elements;
        bb = {
          x1: bbe.x1,
          y1: bbe.y1,
          x2: bbe.x2,
          y2: bbe.y2
        };
        bb.w = bb.x2 - bb.x1;
        bb.h = bb.y2 - bb.y1;
      } else if (!elementOrCollection(elements)) {
        elements = this.mutableElements();
      }
      if (elementOrCollection(elements) && elements.empty()) {
        return;
      } // can't fit to nothing

      bb = bb || elements.boundingBox();
      var w = this.width();
      var h = this.height();
      var zoom;
      padding = number$1(padding) ? padding : 0;
      if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0) {
        zoom = Math.min((w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h);

        // crop zoom
        zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;
        zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;
        var pan = {
          // now pan to middle
          x: (w - zoom * (bb.x1 + bb.x2)) / 2,
          y: (h - zoom * (bb.y1 + bb.y2)) / 2
        };
        return {
          zoom: zoom,
          pan: pan
        };
      }
      return;
    },
    zoomRange: function zoomRange(min, max) {
      var _p = this._private;
      if (max == null) {
        var opts = min;
        min = opts.min;
        max = opts.max;
      }
      if (number$1(min) && number$1(max) && min <= max) {
        _p.minZoom = min;
        _p.maxZoom = max;
      } else if (number$1(min) && max === undefined && min <= _p.maxZoom) {
        _p.minZoom = min;
      } else if (number$1(max) && min === undefined && max >= _p.minZoom) {
        _p.maxZoom = max;
      }
      return this;
    },
    minZoom: function minZoom(zoom) {
      if (zoom === undefined) {
        return this._private.minZoom;
      } else {
        return this.zoomRange({
          min: zoom
        });
      }
    },
    maxZoom: function maxZoom(zoom) {
      if (zoom === undefined) {
        return this._private.maxZoom;
      } else {
        return this.zoomRange({
          max: zoom
        });
      }
    },
    getZoomedViewport: function getZoomedViewport(params) {
      var _p = this._private;
      var currentPan = _p.pan;
      var currentZoom = _p.zoom;
      var pos; // in rendered px
      var zoom;
      var bail = false;
      if (!_p.zoomingEnabled) {
        // zooming disabled
        bail = true;
      }
      if (number$1(params)) {
        // then set the zoom
        zoom = params;
      } else if (plainObject(params)) {
        // then zoom about a point
        zoom = params.level;
        if (params.position != null) {
          pos = modelToRenderedPosition(params.position, currentZoom, currentPan);
        } else if (params.renderedPosition != null) {
          pos = params.renderedPosition;
        }
        if (pos != null && !_p.panningEnabled) {
          // panning disabled
          bail = true;
        }
      }

      // crop zoom
      zoom = zoom > _p.maxZoom ? _p.maxZoom : zoom;
      zoom = zoom < _p.minZoom ? _p.minZoom : zoom;

      // can't zoom with invalid params
      if (bail || !number$1(zoom) || zoom === currentZoom || pos != null && (!number$1(pos.x) || !number$1(pos.y))) {
        return null;
      }
      if (pos != null) {
        // set zoom about position
        var pan1 = currentPan;
        var zoom1 = currentZoom;
        var zoom2 = zoom;
        var pan2 = {
          x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x,
          y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y
        };
        return {
          zoomed: true,
          panned: true,
          zoom: zoom2,
          pan: pan2
        };
      } else {
        // just set the zoom
        return {
          zoomed: true,
          panned: false,
          zoom: zoom,
          pan: currentPan
        };
      }
    },
    zoom: function zoom(params) {
      if (params === undefined) {
        // get
        return this._private.zoom;
      } else {
        // set
        var vp = this.getZoomedViewport(params);
        var _p = this._private;
        if (vp == null || !vp.zoomed) {
          return this;
        }
        _p.zoom = vp.zoom;
        if (vp.panned) {
          _p.pan.x = vp.pan.x;
          _p.pan.y = vp.pan.y;
        }
        this.emit('zoom' + (vp.panned ? ' pan' : '') + ' viewport');
        this.notify('viewport');
        return this; // chaining
      }
    },

    viewport: function viewport(opts) {
      var _p = this._private;
      var zoomDefd = true;
      var panDefd = true;
      var events = []; // to trigger
      var zoomFailed = false;
      var panFailed = false;
      if (!opts) {
        return this;
      }
      if (!number$1(opts.zoom)) {
        zoomDefd = false;
      }
      if (!plainObject(opts.pan)) {
        panDefd = false;
      }
      if (!zoomDefd && !panDefd) {
        return this;
      }
      if (zoomDefd) {
        var z = opts.zoom;
        if (z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled) {
          zoomFailed = true;
        } else {
          _p.zoom = z;
          events.push('zoom');
        }
      }
      if (panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled) {
        var p = opts.pan;
        if (number$1(p.x)) {
          _p.pan.x = p.x;
          panFailed = false;
        }
        if (number$1(p.y)) {
          _p.pan.y = p.y;
          panFailed = false;
        }
        if (!panFailed) {
          events.push('pan');
        }
      }
      if (events.length > 0) {
        events.push('viewport');
        this.emit(events.join(' '));
        this.notify('viewport');
      }
      return this; // chaining
    },

    center: function center(elements) {
      var pan = this.getCenterPan(elements);
      if (pan) {
        this._private.pan = pan;
        this.emit('pan viewport');
        this.notify('viewport');
      }
      return this; // chaining
    },

    getCenterPan: function getCenterPan(elements, zoom) {
      if (!this._private.panningEnabled) {
        return;
      }
      if (string(elements)) {
        var selector = elements;
        elements = this.mutableElements().filter(selector);
      } else if (!elementOrCollection(elements)) {
        elements = this.mutableElements();
      }
      if (elements.length === 0) {
        return;
      } // can't centre pan to nothing

      var bb = elements.boundingBox();
      var w = this.width();
      var h = this.height();
      zoom = zoom === undefined ? this._private.zoom : zoom;
      var pan = {
        // middle
        x: (w - zoom * (bb.x1 + bb.x2)) / 2,
        y: (h - zoom * (bb.y1 + bb.y2)) / 2
      };
      return pan;
    },
    reset: function reset() {
      if (!this._private.panningEnabled || !this._private.zoomingEnabled) {
        return this;
      }
      this.viewport({
        pan: {
          x: 0,
          y: 0
        },
        zoom: 1
      });
      return this; // chaining
    },

    invalidateSize: function invalidateSize() {
      this._private.sizeCache = null;
    },
    size: function size() {
      var _p = this._private;
      var container = _p.container;
      var cy = this;
      return _p.sizeCache = _p.sizeCache || (container ? function () {
        var style = cy.window().getComputedStyle(container);
        var val = function val(name) {
          return parseFloat(style.getPropertyValue(name));
        };
        return {
          width: container.clientWidth - val('padding-left') - val('padding-right'),
          height: container.clientHeight - val('padding-top') - val('padding-bottom')
        };
      }() : {
        // fallback if no container (not 0 b/c can be used for dividing etc)
        width: 1,
        height: 1
      });
    },
    width: function width() {
      return this.size().width;
    },
    height: function height() {
      return this.size().height;
    },
    extent: function extent() {
      var pan = this._private.pan;
      var zoom = this._private.zoom;
      var rb = this.renderedExtent();
      var b = {
        x1: (rb.x1 - pan.x) / zoom,
        x2: (rb.x2 - pan.x) / zoom,
        y1: (rb.y1 - pan.y) / zoom,
        y2: (rb.y2 - pan.y) / zoom
      };
      b.w = b.x2 - b.x1;
      b.h = b.y2 - b.y1;
      return b;
    },
    renderedExtent: function renderedExtent() {
      var width = this.width();
      var height = this.height();
      return {
        x1: 0,
        y1: 0,
        x2: width,
        y2: height,
        w: width,
        h: height
      };
    },
    multiClickDebounceTime: function multiClickDebounceTime(_int) {
      if (_int) this._private.multiClickDebounceTime = _int;else return this._private.multiClickDebounceTime;
      return this; // chaining
    }
  };

  // aliases
  corefn$1.centre = corefn$1.center;

  // backwards compatibility
  corefn$1.autolockNodes = corefn$1.autolock;
  corefn$1.autoungrabifyNodes = corefn$1.autoungrabify;

  var fn = {
    data: define.data({
      field: 'data',
      bindingEvent: 'data',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'data',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeData: define.removeData({
      field: 'data',
      event: 'data',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    }),
    scratch: define.data({
      field: 'scratch',
      bindingEvent: 'scratch',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'scratch',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeScratch: define.removeData({
      field: 'scratch',
      event: 'scratch',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    })
  };

  // aliases
  fn.attr = fn.data;
  fn.removeAttr = fn.removeData;

  var Core = function Core(opts) {
    var cy = this;
    opts = extend({}, opts);
    var container = opts.container;

    // allow for passing a wrapped jquery object
    // e.g. cytoscape({ container: $('#cy') })
    if (container && !htmlElement(container) && htmlElement(container[0])) {
      container = container[0];
    }
    var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery
    reg = reg || {};
    if (reg && reg.cy) {
      reg.cy.destroy();
      reg = {}; // old instance => replace reg completely
    }

    var readies = reg.readies = reg.readies || [];
    if (container) {
      container._cyreg = reg;
    } // make sure container assoc'd reg points to this cy
    reg.cy = cy;
    var head = _window !== undefined && container !== undefined && !opts.headless;
    var options = opts;
    options.layout = extend({
      name: head ? 'grid' : 'null'
    }, options.layout);
    options.renderer = extend({
      name: head ? 'canvas' : 'null'
    }, options.renderer);
    var defVal = function defVal(def, val, altVal) {
      if (val !== undefined) {
        return val;
      } else if (altVal !== undefined) {
        return altVal;
      } else {
        return def;
      }
    };
    var _p = this._private = {
      container: container,
      // html dom ele container
      ready: false,
      // whether ready has been triggered
      options: options,
      // cached options
      elements: new Collection(this),
      // elements in the graph
      listeners: [],
      // list of listeners
      aniEles: new Collection(this),
      // elements being animated
      data: options.data || {},
      // data for the core
      scratch: {},
      // scratch object for core
      layout: null,
      renderer: null,
      destroyed: false,
      // whether destroy was called
      notificationsEnabled: true,
      // whether notifications are sent to the renderer
      minZoom: 1e-50,
      maxZoom: 1e50,
      zoomingEnabled: defVal(true, options.zoomingEnabled),
      userZoomingEnabled: defVal(true, options.userZoomingEnabled),
      panningEnabled: defVal(true, options.panningEnabled),
      userPanningEnabled: defVal(true, options.userPanningEnabled),
      boxSelectionEnabled: defVal(true, options.boxSelectionEnabled),
      autolock: defVal(false, options.autolock, options.autolockNodes),
      autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes),
      autounselectify: defVal(false, options.autounselectify),
      styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled,
      zoom: number$1(options.zoom) ? options.zoom : 1,
      pan: {
        x: plainObject(options.pan) && number$1(options.pan.x) ? options.pan.x : 0,
        y: plainObject(options.pan) && number$1(options.pan.y) ? options.pan.y : 0
      },
      animation: {
        // object for currently-running animations
        current: [],
        queue: []
      },
      hasCompoundNodes: false,
      multiClickDebounceTime: defVal(250, options.multiClickDebounceTime)
    };
    this.createEmitter();

    // set selection type
    this.selectionType(options.selectionType);

    // init zoom bounds
    this.zoomRange({
      min: options.minZoom,
      max: options.maxZoom
    });
    var loadExtData = function loadExtData(extData, next) {
      var anyIsPromise = extData.some(promise);
      if (anyIsPromise) {
        return Promise$1.all(extData).then(next); // load all data asynchronously, then exec rest of init
      } else {
        next(extData); // exec synchronously for convenience
      }
    };

    // start with the default stylesheet so we have something before loading an external stylesheet
    if (_p.styleEnabled) {
      cy.setStyle([]);
    }

    // create the renderer
    var rendererOptions = extend({}, options, options.renderer); // allow rendering hints in top level options
    cy.initRenderer(rendererOptions);
    var setElesAndLayout = function setElesAndLayout(elements, onload, ondone) {
      cy.notifications(false);

      // remove old elements
      var oldEles = cy.mutableElements();
      if (oldEles.length > 0) {
        oldEles.remove();
      }
      if (elements != null) {
        if (plainObject(elements) || array(elements)) {
          cy.add(elements);
        }
      }
      cy.one('layoutready', function (e) {
        cy.notifications(true);
        cy.emit(e); // we missed this event by turning notifications off, so pass it on

        cy.one('load', onload);
        cy.emitAndNotify('load');
      }).one('layoutstop', function () {
        cy.one('done', ondone);
        cy.emit('done');
      });
      var layoutOpts = extend({}, cy._private.options.layout);
      layoutOpts.eles = cy.elements();
      cy.layout(layoutOpts).run();
    };
    loadExtData([options.style, options.elements], function (thens) {
      var initStyle = thens[0];
      var initEles = thens[1];

      // init style
      if (_p.styleEnabled) {
        cy.style().append(initStyle);
      }

      // initial load
      setElesAndLayout(initEles, function () {
        // onready
        cy.startAnimationLoop();
        _p.ready = true;

        // if a ready callback is specified as an option, the bind it
        if (fn$6(options.ready)) {
          cy.on('ready', options.ready);
        }

        // bind all the ready handlers registered before creating this instance
        for (var i = 0; i < readies.length; i++) {
          var fn = readies[i];
          cy.on('ready', fn);
        }
        if (reg) {
          reg.readies = [];
        } // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc

        cy.emit('ready');
      }, options.done);
    });
  };
  var corefn = Core.prototype; // short alias

  extend(corefn, {
    instanceString: function instanceString() {
      return 'core';
    },
    isReady: function isReady() {
      return this._private.ready;
    },
    destroyed: function destroyed() {
      return this._private.destroyed;
    },
    ready: function ready(fn) {
      if (this.isReady()) {
        this.emitter().emit('ready', [], fn); // just calls fn as though triggered via ready event
      } else {
        this.on('ready', fn);
      }
      return this;
    },
    destroy: function destroy() {
      var cy = this;
      if (cy.destroyed()) return;
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      this.emit('destroy');
      cy._private.destroyed = true;
      return cy;
    },
    hasElementWithId: function hasElementWithId(id) {
      return this._private.elements.hasElementWithId(id);
    },
    getElementById: function getElementById(id) {
      return this._private.elements.getElementById(id);
    },
    hasCompoundNodes: function hasCompoundNodes() {
      return this._private.hasCompoundNodes;
    },
    headless: function headless() {
      return this._private.renderer.isHeadless();
    },
    styleEnabled: function styleEnabled() {
      return this._private.styleEnabled;
    },
    addToPool: function addToPool(eles) {
      this._private.elements.merge(eles);
      return this; // chaining
    },

    removeFromPool: function removeFromPool(eles) {
      this._private.elements.unmerge(eles);
      return this;
    },
    container: function container() {
      return this._private.container || null;
    },
    window: function window() {
      var container = this._private.container;
      if (container == null) return _window;
      var ownerDocument = this._private.container.ownerDocument;
      if (ownerDocument === undefined || ownerDocument == null) {
        return _window;
      }
      return ownerDocument.defaultView || _window;
    },
    mount: function mount(container) {
      if (container == null) {
        return;
      }
      var cy = this;
      var _p = cy._private;
      var options = _p.options;
      if (!htmlElement(container) && htmlElement(container[0])) {
        container = container[0];
      }
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      _p.container = container;
      _p.styleEnabled = true;
      cy.invalidateSize();
      cy.initRenderer(extend({}, options, options.renderer, {
        // allow custom renderer name to be re-used, otherwise use canvas
        name: options.renderer.name === 'null' ? 'canvas' : options.renderer.name
      }));
      cy.startAnimationLoop();
      cy.style(options.style);
      cy.emit('mount');
      return cy;
    },
    unmount: function unmount() {
      var cy = this;
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      cy.initRenderer({
        name: 'null'
      });
      cy.emit('unmount');
      return cy;
    },
    options: function options() {
      return copy(this._private.options);
    },
    json: function json(obj) {
      var cy = this;
      var _p = cy._private;
      var eles = cy.mutableElements();
      var getFreshRef = function getFreshRef(ele) {
        return cy.getElementById(ele.id());
      };
      if (plainObject(obj)) {
        // set

        cy.startBatch();
        if (obj.elements) {
          var idInJson = {};
          var updateEles = function updateEles(jsons, gr) {
            var toAdd = [];
            var toMod = [];
            for (var i = 0; i < jsons.length; i++) {
              var json = jsons[i];
              if (!json.data.id) {
                warn('cy.json() cannot handle elements without an ID attribute');
                continue;
              }
              var id = '' + json.data.id; // id must be string
              var ele = cy.getElementById(id);
              idInJson[id] = true;
              if (ele.length !== 0) {
                // existing element should be updated
                toMod.push({
                  ele: ele,
                  json: json
                });
              } else {
                // otherwise should be added
                if (gr) {
                  json.group = gr;
                  toAdd.push(json);
                } else {
                  toAdd.push(json);
                }
              }
            }
            cy.add(toAdd);
            for (var _i = 0; _i < toMod.length; _i++) {
              var _toMod$_i = toMod[_i],
                _ele = _toMod$_i.ele,
                _json = _toMod$_i.json;
              _ele.json(_json);
            }
          };
          if (array(obj.elements)) {
            // elements: []
            updateEles(obj.elements);
          } else {
            // elements: { nodes: [], edges: [] }
            var grs = ['nodes', 'edges'];
            for (var i = 0; i < grs.length; i++) {
              var gr = grs[i];
              var elements = obj.elements[gr];
              if (array(elements)) {
                updateEles(elements, gr);
              }
            }
          }
          var parentsToRemove = cy.collection();
          eles.filter(function (ele) {
            return !idInJson[ele.id()];
          }).forEach(function (ele) {
            if (ele.isParent()) {
              parentsToRemove.merge(ele);
            } else {
              ele.remove();
            }
          });

          // so that children are not removed w/parent
          parentsToRemove.forEach(function (ele) {
            return ele.children().move({
              parent: null
            });
          });

          // intermediate parents may be moved by prior line, so make sure we remove by fresh refs
          parentsToRemove.forEach(function (ele) {
            return getFreshRef(ele).remove();
          });
        }
        if (obj.style) {
          cy.style(obj.style);
        }
        if (obj.zoom != null && obj.zoom !== _p.zoom) {
          cy.zoom(obj.zoom);
        }
        if (obj.pan) {
          if (obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y) {
            cy.pan(obj.pan);
          }
        }
        if (obj.data) {
          cy.data(obj.data);
        }
        var fields = ['minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'panningEnabled', 'userPanningEnabled', 'boxSelectionEnabled', 'autolock', 'autoungrabify', 'autounselectify', 'multiClickDebounceTime'];
        for (var _i2 = 0; _i2 < fields.length; _i2++) {
          var f = fields[_i2];
          if (obj[f] != null) {
            cy[f](obj[f]);
          }
        }
        cy.endBatch();
        return this; // chaining
      } else {
        // get
        var flat = !!obj;
        var json = {};
        if (flat) {
          json.elements = this.elements().map(function (ele) {
            return ele.json();
          });
        } else {
          json.elements = {};
          eles.forEach(function (ele) {
            var group = ele.group();
            if (!json.elements[group]) {
              json.elements[group] = [];
            }
            json.elements[group].push(ele.json());
          });
        }
        if (this._private.styleEnabled) {
          json.style = cy.style().json();
        }
        json.data = copy(cy.data());
        var options = _p.options;
        json.zoomingEnabled = _p.zoomingEnabled;
        json.userZoomingEnabled = _p.userZoomingEnabled;
        json.zoom = _p.zoom;
        json.minZoom = _p.minZoom;
        json.maxZoom = _p.maxZoom;
        json.panningEnabled = _p.panningEnabled;
        json.userPanningEnabled = _p.userPanningEnabled;
        json.pan = copy(_p.pan);
        json.boxSelectionEnabled = _p.boxSelectionEnabled;
        json.renderer = copy(options.renderer);
        json.hideEdgesOnViewport = options.hideEdgesOnViewport;
        json.textureOnViewport = options.textureOnViewport;
        json.wheelSensitivity = options.wheelSensitivity;
        json.motionBlur = options.motionBlur;
        json.multiClickDebounceTime = options.multiClickDebounceTime;
        return json;
      }
    }
  });
  corefn.$id = corefn.getElementById;
  [corefn$9, corefn$8, elesfn, corefn$7, corefn$6, corefn$5, corefn$4, corefn$3, corefn$2, corefn$1, fn].forEach(function (props) {
    extend(corefn, props);
  });

  /* eslint-disable no-unused-vars */
  var defaults$7 = {
    fit: true,
    // whether to fit the viewport to the graph
    directed: false,
    // whether the tree is directed downwards (or edges can point in any direction if false)
    padding: 30,
    // padding on fit
    circle: false,
    // put depths in concentric circles if true, put depths top down if false
    grid: false,
    // whether to create an even grid into which the DAG is placed (circle:false only)
    spacingFactor: 1.75,
    // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    roots: undefined,
    // the roots of the trees
    depthSort: undefined,
    // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled,
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  var deprecatedOptionDefaults = {
    maximal: false,
    // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only); setting acyclic to true sets maximal to true also
    acyclic: false // whether the tree is acyclic and thus a node could be shifted (due to the maximal option) multiple times without causing an infinite loop; setting to true sets maximal to true also; if you are uncertain whether a tree is acyclic, set to false to avoid potential infinite loops
  };

  /* eslint-enable */

  var getInfo = function getInfo(ele) {
    return ele.scratch('breadthfirst');
  };
  var setInfo = function setInfo(ele, obj) {
    return ele.scratch('breadthfirst', obj);
  };
  function BreadthFirstLayout(options) {
    this.options = extend({}, defaults$7, deprecatedOptionDefaults, options);
  }
  BreadthFirstLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().filter(function (n) {
      return !n.isParent();
    });
    var graph = eles;
    var directed = options.directed;
    var maximal = options.acyclic || options.maximal || options.maximalAdjustments > 0; // maximalAdjustments for compat. w/ old code; also, setting acyclic to true sets maximal to true

    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var roots;
    if (elementOrCollection(options.roots)) {
      roots = options.roots;
    } else if (array(options.roots)) {
      var rootsArray = [];
      for (var i = 0; i < options.roots.length; i++) {
        var id = options.roots[i];
        var ele = cy.getElementById(id);
        rootsArray.push(ele);
      }
      roots = cy.collection(rootsArray);
    } else if (string(options.roots)) {
      roots = cy.$(options.roots);
    } else {
      if (directed) {
        roots = nodes.roots();
      } else {
        var components = eles.components();
        roots = cy.collection();
        var _loop = function _loop(_i) {
          var comp = components[_i];
          var maxDegree = comp.maxDegree(false);
          var compRoots = comp.filter(function (ele) {
            return ele.degree(false) === maxDegree;
          });
          roots = roots.add(compRoots);
        };
        for (var _i = 0; _i < components.length; _i++) {
          _loop(_i);
        }
      }
    }
    var depths = [];
    var foundByBfs = {};
    var addToDepth = function addToDepth(ele, d) {
      if (depths[d] == null) {
        depths[d] = [];
      }
      var i = depths[d].length;
      depths[d].push(ele);
      setInfo(ele, {
        index: i,
        depth: d
      });
    };
    var changeDepth = function changeDepth(ele, newDepth) {
      var _getInfo = getInfo(ele),
        depth = _getInfo.depth,
        index = _getInfo.index;
      depths[depth][index] = null;
      addToDepth(ele, newDepth);
    };

    // find the depths of the nodes
    graph.bfs({
      roots: roots,
      directed: options.directed,
      visit: function visit(node, edge, pNode, i, depth) {
        var ele = node[0];
        var id = ele.id();
        addToDepth(ele, depth);
        foundByBfs[id] = true;
      }
    });

    // check for nodes not found by bfs
    var orphanNodes = [];
    for (var _i2 = 0; _i2 < nodes.length; _i2++) {
      var _ele = nodes[_i2];
      if (foundByBfs[_ele.id()]) {
        continue;
      } else {
        orphanNodes.push(_ele);
      }
    }

    // assign the nodes a depth and index

    var assignDepthsAt = function assignDepthsAt(i) {
      var eles = depths[i];
      for (var j = 0; j < eles.length; j++) {
        var _ele2 = eles[j];
        if (_ele2 == null) {
          eles.splice(j, 1);
          j--;
          continue;
        }
        setInfo(_ele2, {
          depth: i,
          index: j
        });
      }
    };
    var assignDepths = function assignDepths() {
      for (var _i3 = 0; _i3 < depths.length; _i3++) {
        assignDepthsAt(_i3);
      }
    };
    var adjustMaximally = function adjustMaximally(ele, shifted) {
      var eInfo = getInfo(ele);
      var incomers = ele.incomers().filter(function (el) {
        return el.isNode() && eles.has(el);
      });
      var maxDepth = -1;
      var id = ele.id();
      for (var k = 0; k < incomers.length; k++) {
        var incmr = incomers[k];
        var iInfo = getInfo(incmr);
        maxDepth = Math.max(maxDepth, iInfo.depth);
      }
      if (eInfo.depth <= maxDepth) {
        if (!options.acyclic && shifted[id]) {
          return null;
        }
        var newDepth = maxDepth + 1;
        changeDepth(ele, newDepth);
        shifted[id] = newDepth;
        return true;
      }
      return false;
    };

    // for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1)
    if (directed && maximal) {
      var Q = [];
      var shifted = {};
      var enqueue = function enqueue(n) {
        return Q.push(n);
      };
      var dequeue = function dequeue() {
        return Q.shift();
      };
      nodes.forEach(function (n) {
        return Q.push(n);
      });
      while (Q.length > 0) {
        var _ele3 = dequeue();
        var didShift = adjustMaximally(_ele3, shifted);
        if (didShift) {
          _ele3.outgoers().filter(function (el) {
            return el.isNode() && eles.has(el);
          }).forEach(enqueue);
        } else if (didShift === null) {
          warn('Detected double maximal shift for node `' + _ele3.id() + '`.  Bailing maximal adjustment due to cycle.  Use `options.maximal: true` only on DAGs.');
          break; // exit on failure
        }
      }
    }

    assignDepths(); // clear holes

    // find min distance we need to leave between nodes
    var minDistance = 0;
    if (options.avoidOverlap) {
      for (var _i4 = 0; _i4 < nodes.length; _i4++) {
        var n = nodes[_i4];
        var nbb = n.layoutDimensions(options);
        var w = nbb.w;
        var h = nbb.h;
        minDistance = Math.max(minDistance, w, h);
      }
    }

    // get the weighted percent for an element based on its connectivity to other levels
    var cachedWeightedPercent = {};
    var getWeightedPercent = function getWeightedPercent(ele) {
      if (cachedWeightedPercent[ele.id()]) {
        return cachedWeightedPercent[ele.id()];
      }
      var eleDepth = getInfo(ele).depth;
      var neighbors = ele.neighborhood();
      var percent = 0;
      var samples = 0;
      for (var _i5 = 0; _i5 < neighbors.length; _i5++) {
        var neighbor = neighbors[_i5];
        if (neighbor.isEdge() || neighbor.isParent() || !nodes.has(neighbor)) {
          continue;
        }
        var bf = getInfo(neighbor);
        if (bf == null) {
          continue;
        }
        var index = bf.index;
        var depth = bf.depth;

        // unassigned neighbours shouldn't affect the ordering
        if (index == null || depth == null) {
          continue;
        }
        var nDepth = depths[depth].length;
        if (depth < eleDepth) {
          // only get influenced by elements above
          percent += index / nDepth;
          samples++;
        }
      }
      samples = Math.max(1, samples);
      percent = percent / samples;
      if (samples === 0) {
        // put lone nodes at the start
        percent = 0;
      }
      cachedWeightedPercent[ele.id()] = percent;
      return percent;
    };

    // rearrange the indices in each depth level based on connectivity

    var sortFn = function sortFn(a, b) {
      var apct = getWeightedPercent(a);
      var bpct = getWeightedPercent(b);
      var diff = apct - bpct;
      if (diff === 0) {
        return ascending(a.id(), b.id()); // make sure sort doesn't have don't-care comparisons
      } else {
        return diff;
      }
    };
    if (options.depthSort !== undefined) {
      sortFn = options.depthSort;
    }

    // sort each level to make connected nodes closer
    for (var _i6 = 0; _i6 < depths.length; _i6++) {
      depths[_i6].sort(sortFn);
      assignDepthsAt(_i6);
    }

    // assign orphan nodes to a new top-level depth
    var orphanDepth = [];
    for (var _i7 = 0; _i7 < orphanNodes.length; _i7++) {
      orphanDepth.push(orphanNodes[_i7]);
    }
    depths.unshift(orphanDepth);
    assignDepths();
    var biggestDepthSize = 0;
    for (var _i8 = 0; _i8 < depths.length; _i8++) {
      biggestDepthSize = Math.max(depths[_i8].length, biggestDepthSize);
    }
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.x1 + bb.h / 2
    };
    var maxDepthSize = depths.reduce(function (max, eles) {
      return Math.max(max, eles.length);
    }, 0);
    var getPosition = function getPosition(ele) {
      var _getInfo2 = getInfo(ele),
        depth = _getInfo2.depth,
        index = _getInfo2.index;
      var depthSize = depths[depth].length;
      var distanceX = Math.max(bb.w / ((options.grid ? maxDepthSize : depthSize) + 1), minDistance);
      var distanceY = Math.max(bb.h / (depths.length + 1), minDistance);
      var radiusStepSize = Math.min(bb.w / 2 / depths.length, bb.h / 2 / depths.length);
      radiusStepSize = Math.max(radiusStepSize, minDistance);
      if (!options.circle) {
        var epos = {
          x: center.x + (index + 1 - (depthSize + 1) / 2) * distanceX,
          y: (depth + 1) * distanceY
        };
        return epos;
      } else {
        var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize / 2 : 0);
        var theta = 2 * Math.PI / depths[depth].length * index;
        if (depth === 0 && depths[0].length === 1) {
          radius = 1;
        }
        return {
          x: center.x + radius * Math.cos(theta),
          y: center.y + radius * Math.sin(theta)
        };
      }
    };
    eles.nodes().layoutPositions(this, options, getPosition);
    return this; // chaining
  };

  var defaults$6 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // the padding on fit
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox and radius if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    radius: undefined,
    // the radius of the circle
    startAngle: 3 / 2 * Math.PI,
    // where nodes start in radians
    sweep: undefined,
    // how many radians should be between the first and last node (defaults to full circle)
    clockwise: true,
    // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
    sort: undefined,
    // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function CircleLayout(options) {
    this.options = extend({}, defaults$6, options);
  }
  CircleLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
    var nodes = eles.nodes().not(':parent');
    if (options.sort) {
      nodes = nodes.sort(options.sort);
    }
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.y1 + bb.h / 2
    };
    var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep;
    var dTheta = sweep / Math.max(1, nodes.length - 1);
    var r;
    var minDistance = 0;
    for (var i = 0; i < nodes.length; i++) {
      var n = nodes[i];
      var nbb = n.layoutDimensions(options);
      var w = nbb.w;
      var h = nbb.h;
      minDistance = Math.max(minDistance, w, h);
    }
    if (number$1(options.radius)) {
      r = options.radius;
    } else if (nodes.length <= 1) {
      r = 0;
    } else {
      r = Math.min(bb.h, bb.w) / 2 - minDistance;
    }

    // calculate the radius
    if (nodes.length > 1 && options.avoidOverlap) {
      // but only if more than one node (can't overlap)
      minDistance *= 1.75; // just to have some nice spacing

      var dcos = Math.cos(dTheta) - Math.cos(0);
      var dsin = Math.sin(dTheta) - Math.sin(0);
      var rMin = Math.sqrt(minDistance * minDistance / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping
      r = Math.max(rMin, r);
    }
    var getPos = function getPos(ele, i) {
      var theta = options.startAngle + i * dTheta * (clockwise ? 1 : -1);
      var rx = r * Math.cos(theta);
      var ry = r * Math.sin(theta);
      var pos = {
        x: center.x + rx,
        y: center.y + ry
      };
      return pos;
    };
    eles.nodes().layoutPositions(this, options, getPos);
    return this; // chaining
  };

  var defaults$5 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // the padding on fit
    startAngle: 3 / 2 * Math.PI,
    // where nodes start in radians
    sweep: undefined,
    // how many radians should be between the first and last node (defaults to full circle)
    clockwise: true,
    // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
    equidistant: false,
    // whether levels have an equal radial distance betwen them, may cause bounding box overflow
    minNodeSpacing: 10,
    // min spacing between outside of nodes (used for radius adjustment)
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    height: undefined,
    // height of layout area (overrides container height)
    width: undefined,
    // width of layout area (overrides container width)
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    concentric: function concentric(node) {
      // returns numeric value for each node, placing higher nodes in levels towards the centre
      return node.degree();
    },
    levelWidth: function levelWidth(nodes) {
      // the variation of concentric values in each level
      return nodes.maxDegree() / 4;
    },
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  function ConcentricLayout(options) {
    this.options = extend({}, defaults$5, options);
  }
  ConcentricLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.y1 + bb.h / 2
    };
    var nodeValues = []; // { node, value }
    var maxNodeSize = 0;
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var value = void 0;

      // calculate the node value
      value = options.concentric(node);
      nodeValues.push({
        value: value,
        node: node
      });

      // for style mapping
      node._private.scratch.concentric = value;
    }

    // in case we used the `concentric` in style
    nodes.updateStyle();

    // calculate max size now based on potentially updated mappers
    for (var _i = 0; _i < nodes.length; _i++) {
      var _node = nodes[_i];
      var nbb = _node.layoutDimensions(options);
      maxNodeSize = Math.max(maxNodeSize, nbb.w, nbb.h);
    }

    // sort node values in descreasing order
    nodeValues.sort(function (a, b) {
      return b.value - a.value;
    });
    var levelWidth = options.levelWidth(nodes);

    // put the values into levels
    var levels = [[]];
    var currentLevel = levels[0];
    for (var _i2 = 0; _i2 < nodeValues.length; _i2++) {
      var val = nodeValues[_i2];
      if (currentLevel.length > 0) {
        var diff = Math.abs(currentLevel[0].value - val.value);
        if (diff >= levelWidth) {
          currentLevel = [];
          levels.push(currentLevel);
        }
      }
      currentLevel.push(val);
    }

    // create positions from levels

    var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes

    if (!options.avoidOverlap) {
      // then strictly constrain to bb
      var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;
      var maxR = Math.min(bb.w, bb.h) / 2 - minDist;
      var rStep = maxR / (levels.length + firstLvlHasMulti ? 1 : 0);
      minDist = Math.min(minDist, rStep);
    }

    // find the metrics for each level
    var r = 0;
    for (var _i3 = 0; _i3 < levels.length; _i3++) {
      var level = levels[_i3];
      var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep;
      var dTheta = level.dTheta = sweep / Math.max(1, level.length - 1);

      // calculate the radius
      if (level.length > 1 && options.avoidOverlap) {
        // but only if more than one node (can't overlap)
        var dcos = Math.cos(dTheta) - Math.cos(0);
        var dsin = Math.sin(dTheta) - Math.sin(0);
        var rMin = Math.sqrt(minDist * minDist / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping

        r = Math.max(rMin, r);
      }
      level.r = r;
      r += minDist;
    }
    if (options.equidistant) {
      var rDeltaMax = 0;
      var _r = 0;
      for (var _i4 = 0; _i4 < levels.length; _i4++) {
        var _level = levels[_i4];
        var rDelta = _level.r - _r;
        rDeltaMax = Math.max(rDeltaMax, rDelta);
      }
      _r = 0;
      for (var _i5 = 0; _i5 < levels.length; _i5++) {
        var _level2 = levels[_i5];
        if (_i5 === 0) {
          _r = _level2.r;
        }
        _level2.r = _r;
        _r += rDeltaMax;
      }
    }

    // calculate the node positions
    var pos = {}; // id => position
    for (var _i6 = 0; _i6 < levels.length; _i6++) {
      var _level3 = levels[_i6];
      var _dTheta = _level3.dTheta;
      var _r2 = _level3.r;
      for (var j = 0; j < _level3.length; j++) {
        var _val = _level3[j];
        var theta = options.startAngle + (clockwise ? 1 : -1) * _dTheta * j;
        var p = {
          x: center.x + _r2 * Math.cos(theta),
          y: center.y + _r2 * Math.sin(theta)
        };
        pos[_val.node.id()] = p;
      }
    }

    // position the nodes
    eles.nodes().layoutPositions(this, options, function (ele) {
      var id = ele.id();
      return pos[id];
    });
    return this; // chaining
  };

  /*
  The CoSE layout was written by Gerardo Huck.
  https://www.linkedin.com/in/gerardohuck/

  Based on the following article:
  http://dl.acm.org/citation.cfm?id=1498047

  Modifications tracked on Github.
  */
  var DEBUG;

  /**
   * @brief :  default layout options
   */
  var defaults$4 = {
    // Called on `layoutready`
    ready: function ready() {},
    // Called on `layoutstop`
    stop: function stop() {},
    // Whether to animate while running the layout
    // true : Animate continuously as the layout is running
    // false : Just show the end result
    // 'end' : Animate with the end result, from the initial positions to the end positions
    animate: true,
    // Easing of the animation for animate:'end'
    animationEasing: undefined,
    // The duration of the animation for animate:'end'
    animationDuration: undefined,
    // A function that determines whether the node should be animated
    // All nodes animated by default on animate enabled
    // Non-animated nodes are positioned immediately when the layout starts
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // The layout animates only after this many milliseconds for animate:true
    // (prevents flashing on fast runs)
    animationThreshold: 250,
    // Number of iterations between consecutive screen positions update
    refresh: 20,
    // Whether to fit the network view after when done
    fit: true,
    // Padding on fit
    padding: 30,
    // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    boundingBox: undefined,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    nodeDimensionsIncludeLabels: false,
    // Randomize the initial positions of the nodes (true) or use existing positions (false)
    randomize: false,
    // Extra spacing between components in non-compound graphs
    componentSpacing: 40,
    // Node repulsion (non overlapping) multiplier
    nodeRepulsion: function nodeRepulsion(node) {
      return 2048;
    },
    // Node repulsion (overlapping) multiplier
    nodeOverlap: 4,
    // Ideal edge (non nested) length
    idealEdgeLength: function idealEdgeLength(edge) {
      return 32;
    },
    // Divisor to compute edge forces
    edgeElasticity: function edgeElasticity(edge) {
      return 32;
    },
    // Nesting factor (multiplier) to compute ideal edge length for nested edges
    nestingFactor: 1.2,
    // Gravity force (constant)
    gravity: 1,
    // Maximum number of iterations to perform
    numIter: 1000,
    // Initial temperature (maximum node displacement)
    initialTemp: 1000,
    // Cooling factor (how the temperature is reduced between consecutive iterations
    coolingFactor: 0.99,
    // Lower temperature threshold (below this point the layout will end)
    minTemp: 1.0
  };

  /**
   * @brief       : constructor
   * @arg options : object containing layout options
   */
  function CoseLayout(options) {
    this.options = extend({}, defaults$4, options);
    this.options.layout = this;

    // Exclude any edge that has a source or target node that is not in the set of passed-in nodes
    var nodes = this.options.eles.nodes();
    var edges = this.options.eles.edges();
    var notEdges = edges.filter(function (e) {
      var sourceId = e.source().data('id');
      var targetId = e.target().data('id');
      var hasSource = nodes.some(function (n) {
        return n.data('id') === sourceId;
      });
      var hasTarget = nodes.some(function (n) {
        return n.data('id') === targetId;
      });
      return !hasSource || !hasTarget;
    });
    this.options.eles = this.options.eles.not(notEdges);
  }

  /**
   * @brief : runs the layout
   */
  CoseLayout.prototype.run = function () {
    var options = this.options;
    var cy = options.cy;
    var layout = this;
    layout.stopped = false;
    if (options.animate === true || options.animate === false) {
      layout.emit({
        type: 'layoutstart',
        layout: layout
      });
    }

    // Set DEBUG - Global variable
    if (true === options.debug) {
      DEBUG = true;
    } else {
      DEBUG = false;
    }

    // Initialize layout info
    var layoutInfo = createLayoutInfo(cy, layout, options);

    // Show LayoutInfo contents if debugging
    if (DEBUG) {
      printLayoutInfo(layoutInfo);
    }

    // If required, randomize node positions
    if (options.randomize) {
      randomizePositions(layoutInfo);
    }
    var startTime = performanceNow();
    var refresh = function refresh() {
      refreshPositions(layoutInfo, cy, options);

      // Fit the graph if necessary
      if (true === options.fit) {
        cy.fit(options.padding);
      }
    };
    var mainLoop = function mainLoop(i) {
      if (layout.stopped || i >= options.numIter) {
        // logDebug("Layout manually stopped. Stopping computation in step " + i);
        return false;
      }

      // Do one step in the phisical simulation
      step(layoutInfo, options);

      // Update temperature
      layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;
      // logDebug("New temperature: " + layoutInfo.temperature);

      if (layoutInfo.temperature < options.minTemp) {
        // logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i);
        return false;
      }
      return true;
    };
    var done = function done() {
      if (options.animate === true || options.animate === false) {
        refresh();

        // Layout has finished
        layout.one('layoutstop', options.stop);
        layout.emit({
          type: 'layoutstop',
          layout: layout
        });
      } else {
        var nodes = options.eles.nodes();
        var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);
        nodes.layoutPositions(layout, options, getScaledPos);
      }
    };
    var i = 0;
    var loopRet = true;
    if (options.animate === true) {
      var frame = function frame() {
        var f = 0;
        while (loopRet && f < options.refresh) {
          loopRet = mainLoop(i);
          i++;
          f++;
        }
        if (!loopRet) {
          // it's done
          separateComponents(layoutInfo, options);
          done();
        } else {
          var now = performanceNow();
          if (now - startTime >= options.animationThreshold) {
            refresh();
          }
          requestAnimationFrame(frame);
        }
      };
      frame();
    } else {
      while (loopRet) {
        loopRet = mainLoop(i);
        i++;
      }
      separateComponents(layoutInfo, options);
      done();
    }
    return this; // chaining
  };

  /**
   * @brief : called on continuous layouts to stop them before they finish
   */
  CoseLayout.prototype.stop = function () {
    this.stopped = true;
    if (this.thread) {
      this.thread.stop();
    }
    this.emit('layoutstop');
    return this; // chaining
  };

  CoseLayout.prototype.destroy = function () {
    if (this.thread) {
      this.thread.stop();
    }
    return this; // chaining
  };

  /**
   * @brief     : Creates an object which is contains all the data
   *              used in the layout process
   * @arg cy    : cytoscape.js object
   * @return    : layoutInfo object initialized
   */
  var createLayoutInfo = function createLayoutInfo(cy, layout, options) {
    // Shortcut
    var edges = options.eles.edges();
    var nodes = options.eles.nodes();
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var layoutInfo = {
      isCompound: cy.hasCompoundNodes(),
      layoutNodes: [],
      idToIndex: {},
      nodeSize: nodes.size(),
      graphSet: [],
      indexToGraph: [],
      layoutEdges: [],
      edgeSize: edges.size(),
      temperature: options.initialTemp,
      clientWidth: bb.w,
      clientHeight: bb.h,
      boundingBox: bb
    };
    var components = options.eles.components();
    var id2cmptId = {};
    for (var i = 0; i < components.length; i++) {
      var component = components[i];
      for (var j = 0; j < component.length; j++) {
        var node = component[j];
        id2cmptId[node.id()] = i;
      }
    }

    // Iterate over all nodes, creating layout nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = nodes[i];
      var nbb = n.layoutDimensions(options);
      var tempNode = {};
      tempNode.isLocked = n.locked();
      tempNode.id = n.data('id');
      tempNode.parentId = n.data('parent');
      tempNode.cmptId = id2cmptId[n.id()];
      tempNode.children = [];
      tempNode.positionX = n.position('x');
      tempNode.positionY = n.position('y');
      tempNode.offsetX = 0;
      tempNode.offsetY = 0;
      tempNode.height = nbb.w;
      tempNode.width = nbb.h;
      tempNode.maxX = tempNode.positionX + tempNode.width / 2;
      tempNode.minX = tempNode.positionX - tempNode.width / 2;
      tempNode.maxY = tempNode.positionY + tempNode.height / 2;
      tempNode.minY = tempNode.positionY - tempNode.height / 2;
      tempNode.padLeft = parseFloat(n.style('padding'));
      tempNode.padRight = parseFloat(n.style('padding'));
      tempNode.padTop = parseFloat(n.style('padding'));
      tempNode.padBottom = parseFloat(n.style('padding'));

      // forces
      tempNode.nodeRepulsion = fn$6(options.nodeRepulsion) ? options.nodeRepulsion(n) : options.nodeRepulsion;

      // Add new node
      layoutInfo.layoutNodes.push(tempNode);
      // Add entry to id-index map
      layoutInfo.idToIndex[tempNode.id] = i;
    }

    // Inline implementation of a queue, used for traversing the graph in BFS order
    var queue = [];
    var start = 0; // Points to the start the queue
    var end = -1; // Points to the end of the queue

    var tempGraph = [];

    // Second pass to add child information and
    // initialize queue for hierarchical traversal
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      var p_id = n.parentId;
      // Check if node n has a parent node
      if (null != p_id) {
        // Add node Id to parent's list of children
        layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);
      } else {
        // If a node doesn't have a parent, then it's in the root graph
        queue[++end] = n.id;
        tempGraph.push(n.id);
      }
    }

    // Add root graph to graphSet
    layoutInfo.graphSet.push(tempGraph);

    // Traverse the graph, level by level,
    while (start <= end) {
      // Get the node to visit and remove it from queue
      var node_id = queue[start++];
      var node_ix = layoutInfo.idToIndex[node_id];
      var node = layoutInfo.layoutNodes[node_ix];
      var children = node.children;
      if (children.length > 0) {
        // Add children nodes as a new graph to graph set
        layoutInfo.graphSet.push(children);
        // Add children to que queue to be visited
        for (var i = 0; i < children.length; i++) {
          queue[++end] = children[i];
        }
      }
    }

    // Create indexToGraph map
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      for (var j = 0; j < graph.length; j++) {
        var index = layoutInfo.idToIndex[graph[j]];
        layoutInfo.indexToGraph[index] = i;
      }
    }

    // Iterate over all edges, creating Layout Edges
    for (var i = 0; i < layoutInfo.edgeSize; i++) {
      var e = edges[i];
      var tempEdge = {};
      tempEdge.id = e.data('id');
      tempEdge.sourceId = e.data('source');
      tempEdge.targetId = e.data('target');

      // Compute ideal length
      var idealLength = fn$6(options.idealEdgeLength) ? options.idealEdgeLength(e) : options.idealEdgeLength;
      var elasticity = fn$6(options.edgeElasticity) ? options.edgeElasticity(e) : options.edgeElasticity;

      // Check if it's an inter graph edge
      var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId];
      var targetIx = layoutInfo.idToIndex[tempEdge.targetId];
      var sourceGraph = layoutInfo.indexToGraph[sourceIx];
      var targetGraph = layoutInfo.indexToGraph[targetIx];
      if (sourceGraph != targetGraph) {
        // Find lowest common graph ancestor
        var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);

        // Compute sum of node depths, relative to lca graph
        var lcaGraph = layoutInfo.graphSet[lca];
        var depth = 0;

        // Source depth
        var tempNode = layoutInfo.layoutNodes[sourceIx];
        while (-1 === lcaGraph.indexOf(tempNode.id)) {
          tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
          depth++;
        }

        // Target depth
        tempNode = layoutInfo.layoutNodes[targetIx];
        while (-1 === lcaGraph.indexOf(tempNode.id)) {
          tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
          depth++;
        }

        // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +
        //  ". Index: " + lca + " Contents: " + lcaGraph.toString() +
        //  ". Depth: " + depth);

        // Update idealLength
        idealLength *= depth * options.nestingFactor;
      }
      tempEdge.idealLength = idealLength;
      tempEdge.elasticity = elasticity;
      layoutInfo.layoutEdges.push(tempEdge);
    }

    // Finally, return layoutInfo object
    return layoutInfo;
  };

  /**
   * @brief : This function finds the index of the lowest common
   *          graph ancestor between 2 nodes in the subtree
   *          (from the graph hierarchy induced tree) whose
   *          root is graphIx
   *
   * @arg node1: node1's ID
   * @arg node2: node2's ID
   * @arg layoutInfo: layoutInfo object
   *
   */
  var findLCA = function findLCA(node1, node2, layoutInfo) {
    // Find their common ancester, starting from the root graph
    var res = findLCA_aux(node1, node2, 0, layoutInfo);
    if (2 > res.count) {
      // If aux function couldn't find the common ancester,
      // then it is the root graph
      return 0;
    } else {
      return res.graph;
    }
  };

  /**
   * @brief          : Auxiliary function used for LCA computation
   *
   * @arg node1      : node1's ID
   * @arg node2      : node2's ID
   * @arg graphIx    : subgraph index
   * @arg layoutInfo : layoutInfo object
   *
   * @return         : object of the form {count: X, graph: Y}, where:
   *                   X is the number of ancestors (max: 2) found in
   *                   graphIx (and it's subgraphs),
   *                   Y is the graph index of the lowest graph containing
   *                   all X nodes
   */
  var findLCA_aux = function findLCA_aux(node1, node2, graphIx, layoutInfo) {
    var graph = layoutInfo.graphSet[graphIx];
    // If both nodes belongs to graphIx
    if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {
      return {
        count: 2,
        graph: graphIx
      };
    }

    // Make recursive calls for all subgraphs
    var c = 0;
    for (var i = 0; i < graph.length; i++) {
      var nodeId = graph[i];
      var nodeIx = layoutInfo.idToIndex[nodeId];
      var children = layoutInfo.layoutNodes[nodeIx].children;

      // If the node has no child, skip it
      if (0 === children.length) {
        continue;
      }
      var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];
      var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);
      if (0 === result.count) {
        // Neither node1 nor node2 are present in this subgraph
        continue;
      } else if (1 === result.count) {
        // One of (node1, node2) is present in this subgraph
        c++;
        if (2 === c) {
          // We've already found both nodes, no need to keep searching
          break;
        }
      } else {
        // Both nodes are present in this subgraph
        return result;
      }
    }
    return {
      count: c,
      graph: graphIx
    };
  };

  /**
   * @brief: printsLayoutInfo into js console
   *         Only used for debbuging
   */
var printLayoutInfo; 

  /**
   * @brief : Randomizes the position of all nodes
   */
  var randomizePositions = function randomizePositions(layoutInfo, cy) {
    var width = layoutInfo.clientWidth;
    var height = layoutInfo.clientHeight;
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];

      // No need to randomize compound nodes or locked nodes
      if (0 === n.children.length && !n.isLocked) {
        n.positionX = Math.random() * width;
        n.positionY = Math.random() * height;
      }
    }
  };
  var getScaleInBoundsFn = function getScaleInBoundsFn(layoutInfo, options, nodes) {
    var bb = layoutInfo.boundingBox;
    var coseBB = {
      x1: Infinity,
      x2: -Infinity,
      y1: Infinity,
      y2: -Infinity
    };
    if (options.boundingBox) {
      nodes.forEach(function (node) {
        var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];
        coseBB.x1 = Math.min(coseBB.x1, lnode.positionX);
        coseBB.x2 = Math.max(coseBB.x2, lnode.positionX);
        coseBB.y1 = Math.min(coseBB.y1, lnode.positionY);
        coseBB.y2 = Math.max(coseBB.y2, lnode.positionY);
      });
      coseBB.w = coseBB.x2 - coseBB.x1;
      coseBB.h = coseBB.y2 - coseBB.y1;
    }
    return function (ele, i) {
      var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];
      if (options.boundingBox) {
        // then add extra bounding box constraint
        var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;
        var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;
        return {
          x: bb.x1 + pctX * bb.w,
          y: bb.y1 + pctY * bb.h
        };
      } else {
        return {
          x: lnode.positionX,
          y: lnode.positionY
        };
      }
    };
  };

  /**
   * @brief          : Updates the positions of nodes in the network
   * @arg layoutInfo : LayoutInfo object
   * @arg cy         : Cytoscape object
   * @arg options    : Layout options
   */
  var refreshPositions = function refreshPositions(layoutInfo, cy, options) {
    // var s = 'Refreshing positions';
    // logDebug(s);

    var layout = options.layout;
    var nodes = options.eles.nodes();
    var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);
    nodes.positions(getScaledPos);

    // Trigger layoutReady only on first call
    if (true !== layoutInfo.ready) {
      // s = 'Triggering layoutready';
      // logDebug(s);
      layoutInfo.ready = true;
      layout.one('layoutready', options.ready);
      layout.emit({
        type: 'layoutready',
        layout: this
      });
    }
  };

  /**
   * @brief : Logs a debug message in JS console, if DEBUG is ON
   */
  // var logDebug = function(text) {
  //   if (DEBUG) {
  //     console.debug(text);
  //   }
  // };

  /**
   * @brief          : Performs one iteration of the physical simulation
   * @arg layoutInfo : LayoutInfo object already initialized
   * @arg cy         : Cytoscape object
   * @arg options    : Layout options
   */
  var step = function step(layoutInfo, options, _step) {
    // var s = "\n\n###############################";
    // s += "\nSTEP: " + step;
    // s += "\n###############################\n";
    // logDebug(s);

    // Calculate node repulsions
    calculateNodeForces(layoutInfo, options);
    // Calculate edge forces
    calculateEdgeForces(layoutInfo);
    // Calculate gravity forces
    calculateGravityForces(layoutInfo, options);
    // Propagate forces from parent to child
    propagateForces(layoutInfo);
    // Update positions based on calculated forces
    updatePositions(layoutInfo);
  };

  /**
   * @brief : Computes the node repulsion forces
   */
  var calculateNodeForces = function calculateNodeForces(layoutInfo, options) {
    // Go through each of the graphs in graphSet
    // Nodes only repel each other if they belong to the same graph
    // var s = 'calculateNodeForces';
    // logDebug(s);
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      var numNodes = graph.length;

      // s = "Set: " + graph.toString();
      // logDebug(s);

      // Now get all the pairs of nodes
      // Only get each pair once, (A, B) = (B, A)
      for (var j = 0; j < numNodes; j++) {
        var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];
        for (var k = j + 1; k < numNodes; k++) {
          var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];
          nodeRepulsion(node1, node2, layoutInfo, options);
        }
      }
    }
  };
  var randomDistance = function randomDistance(max) {
    return -max + 2 * max * Math.random();
  };

  /**
   * @brief : Compute the node repulsion forces between a pair of nodes
   */
  var nodeRepulsion = function nodeRepulsion(node1, node2, layoutInfo, options) {
    // var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id;

    var cmptId1 = node1.cmptId;
    var cmptId2 = node2.cmptId;
    if (cmptId1 !== cmptId2 && !layoutInfo.isCompound) {
      return;
    }

    // Get direction of line connecting both node centers
    var directionX = node2.positionX - node1.positionX;
    var directionY = node2.positionY - node1.positionY;
    var maxRandDist = 1;
    // s += "\ndirectionX: " + directionX + ", directionY: " + directionY;

    // If both centers are the same, apply a random force
    if (0 === directionX && 0 === directionY) {
      directionX = randomDistance(maxRandDist);
      directionY = randomDistance(maxRandDist);
    }
    var overlap = nodesOverlap(node1, node2, directionX, directionY);
    if (overlap > 0) {
      // s += "\nNodes DO overlap.";
      // s += "\nOverlap: " + overlap;
      // If nodes overlap, repulsion force is proportional
      // to the overlap
      var force = options.nodeOverlap * overlap;

      // Compute the module and components of the force vector
      var distance = Math.sqrt(directionX * directionX + directionY * directionY);
      // s += "\nDistance: " + distance;
      var forceX = force * directionX / distance;
      var forceY = force * directionY / distance;
    } else {
      // s += "\nNodes do NOT overlap.";
      // If there's no overlap, force is inversely proportional
      // to squared distance

      // Get clipping points for both nodes
      var point1 = findClippingPoint(node1, directionX, directionY);
      var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);

      // Use clipping points to compute distance
      var distanceX = point2.x - point1.x;
      var distanceY = point2.y - point1.y;
      var distanceSqr = distanceX * distanceX + distanceY * distanceY;
      var distance = Math.sqrt(distanceSqr);
      // s += "\nDistance: " + distance;

      // Compute the module and components of the force vector
      var force = (node1.nodeRepulsion + node2.nodeRepulsion) / distanceSqr;
      var forceX = force * distanceX / distance;
      var forceY = force * distanceY / distance;
    }

    // Apply force
    if (!node1.isLocked) {
      node1.offsetX -= forceX;
      node1.offsetY -= forceY;
    }
    if (!node2.isLocked) {
      node2.offsetX += forceX;
      node2.offsetY += forceY;
    }

    // s += "\nForceX: " + forceX + " ForceY: " + forceY;
    // logDebug(s);

    return;
  };

  /**
   * @brief  : Determines whether two nodes overlap or not
   * @return : Amount of overlapping (0 => no overlap)
   */
  var nodesOverlap = function nodesOverlap(node1, node2, dX, dY) {
    if (dX > 0) {
      var overlapX = node1.maxX - node2.minX;
    } else {
      var overlapX = node2.maxX - node1.minX;
    }
    if (dY > 0) {
      var overlapY = node1.maxY - node2.minY;
    } else {
      var overlapY = node2.maxY - node1.minY;
    }
    if (overlapX >= 0 && overlapY >= 0) {
      return Math.sqrt(overlapX * overlapX + overlapY * overlapY);
    } else {
      return 0;
    }
  };

  /**
   * @brief : Finds the point in which an edge (direction dX, dY) intersects
   *          the rectangular bounding box of it's source/target node
   */
  var findClippingPoint = function findClippingPoint(node, dX, dY) {
    // Shorcuts
    var X = node.positionX;
    var Y = node.positionY;
    var H = node.height || 1;
    var W = node.width || 1;
    var dirSlope = dY / dX;
    var nodeSlope = H / W;

    // var s = 'Computing clipping point of node ' + node.id +
    //   " . Height:  " + H + ", Width: " + W +
    //   "\nDirection " + dX + ", " + dY;
    //
    // Compute intersection
    var res = {};

    // Case: Vertical direction (up)
    if (0 === dX && 0 < dY) {
      res.x = X;
      // s += "\nUp direction";
      res.y = Y + H / 2;
      return res;
    }

    // Case: Vertical direction (down)
    if (0 === dX && 0 > dY) {
      res.x = X;
      res.y = Y + H / 2;
      // s += "\nDown direction";

      return res;
    }

    // Case: Intersects the right border
    if (0 < dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {
      res.x = X + W / 2;
      res.y = Y + W * dY / 2 / dX;
      // s += "\nRightborder";

      return res;
    }

    // Case: Intersects the left border
    if (0 > dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {
      res.x = X - W / 2;
      res.y = Y - W * dY / 2 / dX;
      // s += "\nLeftborder";

      return res;
    }

    // Case: Intersects the top border
    if (0 < dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {
      res.x = X + H * dX / 2 / dY;
      res.y = Y + H / 2;
      // s += "\nTop border";

      return res;
    }

    // Case: Intersects the bottom border
    if (0 > dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {
      res.x = X - H * dX / 2 / dY;
      res.y = Y - H / 2;
      // s += "\nBottom border";

      return res;
    }

    // s += "\nClipping point found at " + res.x + ", " + res.y;
    // logDebug(s);
    return res;
  };

  /**
   * @brief : Calculates all edge forces
   */
  var calculateEdgeForces = function calculateEdgeForces(layoutInfo, options) {
    // Iterate over all edges
    for (var i = 0; i < layoutInfo.edgeSize; i++) {
      // Get edge, source & target nodes
      var edge = layoutInfo.layoutEdges[i];
      var sourceIx = layoutInfo.idToIndex[edge.sourceId];
      var source = layoutInfo.layoutNodes[sourceIx];
      var targetIx = layoutInfo.idToIndex[edge.targetId];
      var target = layoutInfo.layoutNodes[targetIx];

      // Get direction of line connecting both node centers
      var directionX = target.positionX - source.positionX;
      var directionY = target.positionY - source.positionY;

      // If both centers are the same, do nothing.
      // A random force has already been applied as node repulsion
      if (0 === directionX && 0 === directionY) {
        continue;
      }

      // Get clipping points for both nodes
      var point1 = findClippingPoint(source, directionX, directionY);
      var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);
      var lx = point2.x - point1.x;
      var ly = point2.y - point1.y;
      var l = Math.sqrt(lx * lx + ly * ly);
      var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity;
      if (0 !== l) {
        var forceX = force * lx / l;
        var forceY = force * ly / l;
      } else {
        var forceX = 0;
        var forceY = 0;
      }

      // Add this force to target and source nodes
      if (!source.isLocked) {
        source.offsetX += forceX;
        source.offsetY += forceY;
      }
      if (!target.isLocked) {
        target.offsetX -= forceX;
        target.offsetY -= forceY;
      }

      // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;
      // s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")";
      // logDebug(s);
    }
  };

  /**
   * @brief : Computes gravity forces for all nodes
   */
  var calculateGravityForces = function calculateGravityForces(layoutInfo, options) {
    if (options.gravity === 0) {
      return;
    }
    var distThreshold = 1;

    // var s = 'calculateGravityForces';
    // logDebug(s);
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      var numNodes = graph.length;

      // s = "Set: " + graph.toString();
      // logDebug(s);

      // Compute graph center
      if (0 === i) {
        var centerX = layoutInfo.clientHeight / 2;
        var centerY = layoutInfo.clientWidth / 2;
      } else {
        // Get Parent node for this graph, and use its position as center
        var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];
        var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];
        var centerX = parent.positionX;
        var centerY = parent.positionY;
      }
      // s = "Center found at: " + centerX + ", " + centerY;
      // logDebug(s);

      // Apply force to all nodes in graph
      for (var j = 0; j < numNodes; j++) {
        var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];
        // s = "Node: " + node.id;

        if (node.isLocked) {
          continue;
        }
        var dx = centerX - node.positionX;
        var dy = centerY - node.positionY;
        var d = Math.sqrt(dx * dx + dy * dy);
        if (d > distThreshold) {
          var fx = options.gravity * dx / d;
          var fy = options.gravity * dy / d;
          node.offsetX += fx;
          node.offsetY += fy;
          // s += ": Applied force: " + fx + ", " + fy;
        }
        // logDebug(s);
      }
    }
  };

  /**
   * @brief          : This function propagates the existing offsets from
   *                   parent nodes to its descendents.
   * @arg layoutInfo : layoutInfo Object
   * @arg cy         : cytoscape Object
   * @arg options    : Layout options
   */
  var propagateForces = function propagateForces(layoutInfo, options) {
    // Inline implementation of a queue, used for traversing the graph in BFS order
    var queue = [];
    var start = 0; // Points to the start the queue
    var end = -1; // Points to the end of the queue

    // logDebug('propagateForces');

    // Start by visiting the nodes in the root graph
    queue.push.apply(queue, layoutInfo.graphSet[0]);
    end += layoutInfo.graphSet[0].length;

    // Traverse the graph, level by level,
    while (start <= end) {
      // Get the node to visit and remove it from queue
      var nodeId = queue[start++];
      var nodeIndex = layoutInfo.idToIndex[nodeId];
      var node = layoutInfo.layoutNodes[nodeIndex];
      var children = node.children;

      // We only need to process the node if it's compound
      if (0 < children.length && !node.isLocked) {
        var offX = node.offsetX;
        var offY = node.offsetY;

        // var s = "Propagating offset from parent node : " + node.id +
        //   ". OffsetX: " + offX + ". OffsetY: " + offY;
        // s += "\n Children: " + children.toString();
        // logDebug(s);

        for (var i = 0; i < children.length; i++) {
          var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];
          // Propagate offset
          childNode.offsetX += offX;
          childNode.offsetY += offY;
          // Add children to queue to be visited
          queue[++end] = children[i];
        }

        // Reset parent offsets
        node.offsetX = 0;
        node.offsetY = 0;
      }
    }
  };

  /**
   * @brief : Updates the layout model positions, based on
   *          the accumulated forces
   */
  var updatePositions = function updatePositions(layoutInfo, options) {
    // var s = 'Updating positions';
    // logDebug(s);

    // Reset boundaries for compound nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length) {
        // logDebug("Resetting boundaries of compound node: " + n.id);
        n.maxX = undefined;
        n.minX = undefined;
        n.maxY = undefined;
        n.minY = undefined;
      }
    }
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length || n.isLocked) {
        // No need to set compound or locked node position
        // logDebug("Skipping position update of node: " + n.id);
        continue;
      }
      // s = "Node: " + n.id + " Previous position: (" +
      // n.positionX + ", " + n.positionY + ").";

      // Limit displacement in order to improve stability
      var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);
      n.positionX += tempForce.x;
      n.positionY += tempForce.y;
      n.offsetX = 0;
      n.offsetY = 0;
      n.minX = n.positionX - n.width;
      n.maxX = n.positionX + n.width;
      n.minY = n.positionY - n.height;
      n.maxY = n.positionY + n.height;
      // s += " New Position: (" + n.positionX + ", " + n.positionY + ").";
      // logDebug(s);

      // Update ancestry boudaries
      updateAncestryBoundaries(n, layoutInfo);
    }

    // Update size, position of compund nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length && !n.isLocked) {
        n.positionX = (n.maxX + n.minX) / 2;
        n.positionY = (n.maxY + n.minY) / 2;
        n.width = n.maxX - n.minX;
        n.height = n.maxY - n.minY;
        // s = "Updating position, size of compound node " + n.id;
        // s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY;
        // s += "\nWidth: " + n.width + ", Height: " + n.height;
        // logDebug(s);
      }
    }
  };

  /**
   * @brief : Limits a force (forceX, forceY) to be not
   *          greater (in modulo) than max.
   8          Preserves force direction.
    */
  var limitForce = function limitForce(forceX, forceY, max) {
    // var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max;
    var force = Math.sqrt(forceX * forceX + forceY * forceY);
    if (force > max) {
      var res = {
        x: max * forceX / force,
        y: max * forceY / force
      };
    } else {
      var res = {
        x: forceX,
        y: forceY
      };
    }

    // s += ".\nResult: (" + res.x + ", " + res.y + ")";
    // logDebug(s);

    return res;
  };

  /**
   * @brief : Function used for keeping track of compound node
   *          sizes, since they should bound all their subnodes.
   */
  var updateAncestryBoundaries = function updateAncestryBoundaries(node, layoutInfo) {
    // var s = "Propagating new position/size of node " + node.id;
    var parentId = node.parentId;
    if (null == parentId) {
      // If there's no parent, we are done
      // s += ". No parent node.";
      // logDebug(s);
      return;
    }

    // Get Parent Node
    var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];
    var flag = false;

    // MaxX
    if (null == p.maxX || node.maxX + p.padRight > p.maxX) {
      p.maxX = node.maxX + p.padRight;
      flag = true;
      // s += "\nNew maxX for parent node " + p.id + ": " + p.maxX;
    }

    // MinX
    if (null == p.minX || node.minX - p.padLeft < p.minX) {
      p.minX = node.minX - p.padLeft;
      flag = true;
      // s += "\nNew minX for parent node " + p.id + ": " + p.minX;
    }

    // MaxY
    if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {
      p.maxY = node.maxY + p.padBottom;
      flag = true;
      // s += "\nNew maxY for parent node " + p.id + ": " + p.maxY;
    }

    // MinY
    if (null == p.minY || node.minY - p.padTop < p.minY) {
      p.minY = node.minY - p.padTop;
      flag = true;
      // s += "\nNew minY for parent node " + p.id + ": " + p.minY;
    }

    // If updated boundaries, propagate changes upward
    if (flag) {
      // logDebug(s);
      return updateAncestryBoundaries(p, layoutInfo);
    }

    // s += ". No changes in boundaries/position of parent node " + p.id;
    // logDebug(s);
    return;
  };
  var separateComponents = function separateComponents(layoutInfo, options) {
    var nodes = layoutInfo.layoutNodes;
    var components = [];
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var cid = node.cmptId;
      var component = components[cid] = components[cid] || [];
      component.push(node);
    }
    var totalA = 0;
    for (var i = 0; i < components.length; i++) {
      var c = components[i];
      if (!c) {
        continue;
      }
      c.x1 = Infinity;
      c.x2 = -Infinity;
      c.y1 = Infinity;
      c.y2 = -Infinity;
      for (var j = 0; j < c.length; j++) {
        var n = c[j];
        c.x1 = Math.min(c.x1, n.positionX - n.width / 2);
        c.x2 = Math.max(c.x2, n.positionX + n.width / 2);
        c.y1 = Math.min(c.y1, n.positionY - n.height / 2);
        c.y2 = Math.max(c.y2, n.positionY + n.height / 2);
      }
      c.w = c.x2 - c.x1;
      c.h = c.y2 - c.y1;
      totalA += c.w * c.h;
    }
    components.sort(function (c1, c2) {
      return c2.w * c2.h - c1.w * c1.h;
    });
    var x = 0;
    var y = 0;
    var usedW = 0;
    var rowH = 0;
    var maxRowW = Math.sqrt(totalA) * layoutInfo.clientWidth / layoutInfo.clientHeight;
    for (var i = 0; i < components.length; i++) {
      var c = components[i];
      if (!c) {
        continue;
      }
      for (var j = 0; j < c.length; j++) {
        var n = c[j];
        if (!n.isLocked) {
          n.positionX += x - c.x1;
          n.positionY += y - c.y1;
        }
      }
      x += c.w + options.componentSpacing;
      usedW += c.w + options.componentSpacing;
      rowH = Math.max(rowH, c.h);
      if (usedW > maxRowW) {
        y += rowH + options.componentSpacing;
        x = 0;
        usedW = 0;
        rowH = 0;
      }
    }
  };

  var defaults$3 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // padding used on fit
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    avoidOverlapPadding: 10,
    // extra spacing around nodes when avoidOverlap: true
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    condense: false,
    // uses all available space on false, uses minimal space on true
    rows: undefined,
    // force num of rows in the grid
    cols: undefined,
    // force num of columns in the grid
    position: function position(node) {},
    // returns { row, col } for element
    sort: undefined,
    // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function GridLayout(options) {
    this.options = extend({}, defaults$3, options);
  }
  GridLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    if (options.sort) {
      nodes = nodes.sort(options.sort);
    }
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    if (bb.h === 0 || bb.w === 0) {
      eles.nodes().layoutPositions(this, options, function (ele) {
        return {
          x: bb.x1,
          y: bb.y1
        };
      });
    } else {
      // width/height * splits^2 = cells where splits is number of times to split width
      var cells = nodes.size();
      var splits = Math.sqrt(cells * bb.h / bb.w);
      var rows = Math.round(splits);
      var cols = Math.round(bb.w / bb.h * splits);
      var small = function small(val) {
        if (val == null) {
          return Math.min(rows, cols);
        } else {
          var min = Math.min(rows, cols);
          if (min == rows) {
            rows = val;
          } else {
            cols = val;
          }
        }
      };
      var large = function large(val) {
        if (val == null) {
          return Math.max(rows, cols);
        } else {
          var max = Math.max(rows, cols);
          if (max == rows) {
            rows = val;
          } else {
            cols = val;
          }
        }
      };
      var oRows = options.rows;
      var oCols = options.cols != null ? options.cols : options.columns;

      // if rows or columns were set in options, use those values
      if (oRows != null && oCols != null) {
        rows = oRows;
        cols = oCols;
      } else if (oRows != null && oCols == null) {
        rows = oRows;
        cols = Math.ceil(cells / rows);
      } else if (oRows == null && oCols != null) {
        cols = oCols;
        rows = Math.ceil(cells / cols);
      }

      // otherwise use the automatic values and adjust accordingly

      // if rounding was up, see if we can reduce rows or columns
      else if (cols * rows > cells) {
        var sm = small();
        var lg = large();

        // reducing the small side takes away the most cells, so try it first
        if ((sm - 1) * lg >= cells) {
          small(sm - 1);
        } else if ((lg - 1) * sm >= cells) {
          large(lg - 1);
        }
      } else {
        // if rounding was too low, add rows or columns
        while (cols * rows < cells) {
          var _sm = small();
          var _lg = large();

          // try to add to larger side first (adds less in multiplication)
          if ((_lg + 1) * _sm >= cells) {
            large(_lg + 1);
          } else {
            small(_sm + 1);
          }
        }
      }
      var cellWidth = bb.w / cols;
      var cellHeight = bb.h / rows;
      if (options.condense) {
        cellWidth = 0;
        cellHeight = 0;
      }
      if (options.avoidOverlap) {
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var pos = node._private.position;
          if (pos.x == null || pos.y == null) {
            // for bb
            pos.x = 0;
            pos.y = 0;
          }
          var nbb = node.layoutDimensions(options);
          var p = options.avoidOverlapPadding;
          var w = nbb.w + p;
          var h = nbb.h + p;
          cellWidth = Math.max(cellWidth, w);
          cellHeight = Math.max(cellHeight, h);
        }
      }
      var cellUsed = {}; // e.g. 'c-0-2' => true

      var used = function used(row, col) {
        return cellUsed['c-' + row + '-' + col] ? true : false;
      };
      var use = function use(row, col) {
        cellUsed['c-' + row + '-' + col] = true;
      };

      // to keep track of current cell position
      var row = 0;
      var col = 0;
      var moveToNextCell = function moveToNextCell() {
        col++;
        if (col >= cols) {
          col = 0;
          row++;
        }
      };

      // get a cache of all the manual positions
      var id2manPos = {};
      for (var _i = 0; _i < nodes.length; _i++) {
        var _node = nodes[_i];
        var rcPos = options.position(_node);
        if (rcPos && (rcPos.row !== undefined || rcPos.col !== undefined)) {
          // must have at least row or col def'd
          var _pos = {
            row: rcPos.row,
            col: rcPos.col
          };
          if (_pos.col === undefined) {
            // find unused col
            _pos.col = 0;
            while (used(_pos.row, _pos.col)) {
              _pos.col++;
            }
          } else if (_pos.row === undefined) {
            // find unused row
            _pos.row = 0;
            while (used(_pos.row, _pos.col)) {
              _pos.row++;
            }
          }
          id2manPos[_node.id()] = _pos;
          use(_pos.row, _pos.col);
        }
      }
      var getPos = function getPos(element, i) {
        var x, y;
        if (element.locked() || element.isParent()) {
          return false;
        }

        // see if we have a manual position set
        var rcPos = id2manPos[element.id()];
        if (rcPos) {
          x = rcPos.col * cellWidth + cellWidth / 2 + bb.x1;
          y = rcPos.row * cellHeight + cellHeight / 2 + bb.y1;
        } else {
          // otherwise set automatically

          while (used(row, col)) {
            moveToNextCell();
          }
          x = col * cellWidth + cellWidth / 2 + bb.x1;
          y = row * cellHeight + cellHeight / 2 + bb.y1;
          use(row, col);
          moveToNextCell();
        }
        return {
          x: x,
          y: y
        };
      };
      nodes.layoutPositions(this, options, getPos);
    }
    return this; // chaining
  };

  // default layout options
  var defaults$2 = {
    ready: function ready() {},
    // on layoutready
    stop: function stop() {} // on layoutstop
  };

  // constructor
  // options : object containing layout options
  function NullLayout(options) {
    this.options = extend({}, defaults$2, options);
  }

  // runs the layout
  NullLayout.prototype.run = function () {
    var options = this.options;
    var eles = options.eles; // elements to consider in the layout
    var layout = this;

    // cy is automatically populated for us in the constructor
    // (disable eslint for next line as this serves as example layout code to external developers)
    // eslint-disable-next-line no-unused-vars
    options.cy;
    layout.emit('layoutstart');

    // puts all nodes at (0, 0)
    // n.b. most layouts would use layoutPositions(), instead of positions() and manual events
    eles.nodes().positions(function () {
      return {
        x: 0,
        y: 0
      };
    });

    // trigger layoutready when each node has had its position set at least once
    layout.one('layoutready', options.ready);
    layout.emit('layoutready');

    // trigger layoutstop when the layout stops (e.g. finishes)
    layout.one('layoutstop', options.stop);
    layout.emit('layoutstop');
    return this; // chaining
  };

  // called on continuous layouts to stop them before they finish
  NullLayout.prototype.stop = function () {
    return this; // chaining
  };

  var defaults$1 = {
    positions: undefined,
    // map of (node id) => (position obj); or function(node){ return somPos; }
    zoom: undefined,
    // the zoom level to set (prob want fit = false if set)
    pan: undefined,
    // the pan level to set (prob want fit = false if set)
    fit: true,
    // whether to fit to viewport
    padding: 30,
    // padding on fit
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  function PresetLayout(options) {
    this.options = extend({}, defaults$1, options);
  }
  PresetLayout.prototype.run = function () {
    var options = this.options;
    var eles = options.eles;
    var nodes = eles.nodes();
    var posIsFn = fn$6(options.positions);
    function getPosition(node) {
      if (options.positions == null) {
        return copyPosition(node.position());
      }
      if (posIsFn) {
        return options.positions(node);
      }
      var pos = options.positions[node._private.data.id];
      if (pos == null) {
        return null;
      }
      return pos;
    }
    nodes.layoutPositions(this, options, function (node, i) {
      var position = getPosition(node);
      if (node.locked() || position == null) {
        return false;
      }
      return position;
    });
    return this; // chaining
  };

  var defaults = {
    fit: true,
    // whether to fit to viewport
    padding: 30,
    // fit padding
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function RandomLayout(options) {
    this.options = extend({}, defaults, options);
  }
  RandomLayout.prototype.run = function () {
    var options = this.options;
    var cy = options.cy;
    var eles = options.eles;
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var getPos = function getPos(node, i) {
      return {
        x: bb.x1 + Math.round(Math.random() * bb.w),
        y: bb.y1 + Math.round(Math.random() * bb.h)
      };
    };
    eles.nodes().layoutPositions(this, options, getPos);
    return this; // chaining
  };

  var layout = [{
    name: 'breadthfirst',
    impl: BreadthFirstLayout
  }, {
    name: 'circle',
    impl: CircleLayout
  }, {
    name: 'concentric',
    impl: ConcentricLayout
  }, {
    name: 'cose',
    impl: CoseLayout
  }, {
    name: 'grid',
    impl: GridLayout
  }, {
    name: 'null',
    impl: NullLayout
  }, {
    name: 'preset',
    impl: PresetLayout
  }, {
    name: 'random',
    impl: RandomLayout
  }];

  function NullRenderer(options) {
    this.options = options;
    this.notifications = 0; // for testing
  }

  var noop = function noop() {};
  var throwImgErr = function throwImgErr() {
    throw new Error('A headless instance can not render images');
  };
  NullRenderer.prototype = {
    recalculateRenderedStyle: noop,
    notify: function notify() {
      this.notifications++;
    },
    init: noop,
    isHeadless: function isHeadless() {
      return true;
    },
    png: throwImgErr,
    jpg: throwImgErr
  };

  var BRp$f = {};
  BRp$f.arrowShapeWidth = 0.3;
  BRp$f.registerArrowShapes = function () {
    var arrowShapes = this.arrowShapes = {};
    var renderer = this;

    // Contract for arrow shapes:
    // 0, 0 is arrow tip
    // (0, 1) is direction towards node
    // (1, 0) is right
    //
    // functional api:
    // collide: check x, y in shape
    // roughCollide: called before collide, no false negatives
    // draw: draw
    // spacing: dist(arrowTip, nodeBoundary)
    // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip

    var bbCollide = function bbCollide(x, y, size, angle, translation, edgeWidth, padding) {
      var x1 = translation.x - size / 2 - padding;
      var x2 = translation.x + size / 2 + padding;
      var y1 = translation.y - size / 2 - padding;
      var y2 = translation.y + size / 2 + padding;
      var inside = x1 <= x && x <= x2 && y1 <= y && y <= y2;
      return inside;
    };
    var transform = function transform(x, y, size, angle, translation) {
      var xRotated = x * Math.cos(angle) - y * Math.sin(angle);
      var yRotated = x * Math.sin(angle) + y * Math.cos(angle);
      var xScaled = xRotated * size;
      var yScaled = yRotated * size;
      var xTranslated = xScaled + translation.x;
      var yTranslated = yScaled + translation.y;
      return {
        x: xTranslated,
        y: yTranslated
      };
    };
    var transformPoints = function transformPoints(pts, size, angle, translation) {
      var retPts = [];
      for (var i = 0; i < pts.length; i += 2) {
        var x = pts[i];
        var y = pts[i + 1];
        retPts.push(transform(x, y, size, angle, translation));
      }
      return retPts;
    };
    var pointsToArr = function pointsToArr(pts) {
      var ret = [];
      for (var i = 0; i < pts.length; i++) {
        var p = pts[i];
        ret.push(p.x, p.y);
      }
      return ret;
    };
    var standardGap = function standardGap(edge) {
      return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').pfValue * 2;
    };
    var defineArrowShape = function defineArrowShape(name, defn) {
      if (string(defn)) {
        defn = arrowShapes[defn];
      }
      arrowShapes[name] = extend({
        name: name,
        points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3],
        collide: function collide(x, y, size, angle, translation, padding) {
          var points = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
          var inside = pointInsidePolygonPoints(x, y, points);
          return inside;
        },
        roughCollide: bbCollide,
        draw: function draw(context, size, angle, translation) {
          var points = transformPoints(this.points, size, angle, translation);
          renderer.arrowShapeImpl('polygon')(context, points);
        },
        spacing: function spacing(edge) {
          return 0;
        },
        gap: standardGap
      }, defn);
    };
    defineArrowShape('none', {
      collide: falsify,
      roughCollide: falsify,
      draw: noop$1,
      spacing: zeroify,
      gap: zeroify
    });
    defineArrowShape('triangle', {
      points: [-0.15, -0.3, 0, 0, 0.15, -0.3]
    });
    defineArrowShape('arrow', 'triangle');
    defineArrowShape('triangle-backcurve', {
      points: arrowShapes['triangle'].points,
      controlPoint: [0, -0.15],
      roughCollide: bbCollide,
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var ptsTrans = transformPoints(this.points, size, angle, translation);
        var ctrlPt = this.controlPoint;
        var ctrlPtTrans = transform(ctrlPt[0], ctrlPt[1], size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, ptsTrans, ctrlPtTrans);
      },
      gap: function gap(edge) {
        return standardGap(edge) * 0.8;
      }
    });
    defineArrowShape('triangle-tee', {
      points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],
      pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4],
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        var teePts = pointsToArr(transformPoints(this.pointsTee, size + 2 * padding, angle, translation));
        var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.points, size, angle, translation);
        var teePts = transformPoints(this.pointsTee, size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, teePts);
      }
    });
    defineArrowShape('circle-triangle', {
      radius: 0.15,
      pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15],
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var t = translation;
        var circleInside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        return pointInsidePolygonPoints(x, y, triPts) || circleInside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.pointsTr, size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, translation.x, translation.y, this.radius * size);
      },
      spacing: function spacing(edge) {
        return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;
      }
    });
    defineArrowShape('triangle-cross', {
      points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],
      baseCrossLinePts: [-0.15, -0.4,
      // first half of the rectangle
      -0.15, -0.4, 0.15, -0.4,
      // second half of the rectangle
      0.15, -0.4],
      crossLinePts: function crossLinePts(size, edgeWidth) {
        // shift points so that the distance between the cross points matches edge width
        var p = this.baseCrossLinePts.slice();
        var shiftFactor = edgeWidth / size;
        var y0 = 3;
        var y1 = 5;
        p[y0] = p[y0] - shiftFactor;
        p[y1] = p[y1] - shiftFactor;
        return p;
      },
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        var teePts = pointsToArr(transformPoints(this.crossLinePts(size, edgeWidth), size + 2 * padding, angle, translation));
        var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.points, size, angle, translation);
        var crossLinePts = transformPoints(this.crossLinePts(size, edgeWidth), size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, crossLinePts);
      }
    });
    defineArrowShape('vee', {
      points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15],
      gap: function gap(edge) {
        return standardGap(edge) * 0.525;
      }
    });
    defineArrowShape('circle', {
      radius: 0.15,
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var t = translation;
        var inside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        renderer.arrowShapeImpl(this.name)(context, translation.x, translation.y, this.radius * size);
      },
      spacing: function spacing(edge) {
        return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;
      }
    });
    defineArrowShape('tee', {
      points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0],
      spacing: function spacing(edge) {
        return 1;
      },
      gap: function gap(edge) {
        return 1;
      }
    });
    defineArrowShape('square', {
      points: [-0.15, 0.00, 0.15, 0.00, 0.15, -0.3, -0.15, -0.3]
    });
    defineArrowShape('diamond', {
      points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0],
      gap: function gap(edge) {
        return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;
      }
    });
    defineArrowShape('chevron', {
      points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15],
      gap: function gap(edge) {
        return 0.95 * edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;
      }
    });
  };

  var BRp$e = {};

  // Project mouse
  BRp$e.projectIntoViewport = function (clientX, clientY) {
    var cy = this.cy;
    var offsets = this.findContainerClientCoords();
    var offsetLeft = offsets[0];
    var offsetTop = offsets[1];
    var scale = offsets[4];
    var pan = cy.pan();
    var zoom = cy.zoom();
    var x = ((clientX - offsetLeft) / scale - pan.x) / zoom;
    var y = ((clientY - offsetTop) / scale - pan.y) / zoom;
    return [x, y];
  };
  BRp$e.findContainerClientCoords = function () {
    if (this.containerBB) {
      return this.containerBB;
    }
    var container = this.container;
    var rect = container.getBoundingClientRect();
    var style = this.cy.window().getComputedStyle(container);
    var styleValue = function styleValue(name) {
      return parseFloat(style.getPropertyValue(name));
    };
    var padding = {
      left: styleValue('padding-left'),
      right: styleValue('padding-right'),
      top: styleValue('padding-top'),
      bottom: styleValue('padding-bottom')
    };
    var border = {
      left: styleValue('border-left-width'),
      right: styleValue('border-right-width'),
      top: styleValue('border-top-width'),
      bottom: styleValue('border-bottom-width')
    };
    var clientWidth = container.clientWidth;
    var clientHeight = container.clientHeight;
    var paddingHor = padding.left + padding.right;
    var paddingVer = padding.top + padding.bottom;
    var borderHor = border.left + border.right;
    var scale = rect.width / (clientWidth + borderHor);
    var unscaledW = clientWidth - paddingHor;
    var unscaledH = clientHeight - paddingVer;
    var left = rect.left + padding.left + border.left;
    var top = rect.top + padding.top + border.top;
    return this.containerBB = [left, top, unscaledW, unscaledH, scale];
  };
  BRp$e.invalidateContainerClientCoordsCache = function () {
    this.containerBB = null;
  };
  BRp$e.findNearestElement = function (x, y, interactiveElementsOnly, isTouch) {
    return this.findNearestElements(x, y, interactiveElementsOnly, isTouch)[0];
  };
  BRp$e.findNearestElements = function (x, y, interactiveElementsOnly, isTouch) {
    var self = this;
    var r = this;
    var eles = r.getCachedZSortedEles();
    var near = []; // 1 node max, 1 edge max
    var zoom = r.cy.zoom();
    var hasCompounds = r.cy.hasCompoundNodes();
    var edgeThreshold = (isTouch ? 24 : 8) / zoom;
    var nodeThreshold = (isTouch ? 8 : 2) / zoom;
    var labelThreshold = (isTouch ? 8 : 2) / zoom;
    var minSqDist = Infinity;
    var nearEdge;
    var nearNode;
    if (interactiveElementsOnly) {
      eles = eles.interactive;
    }
    function addEle(ele, sqDist) {
      if (ele.isNode()) {
        if (nearNode) {
          return; // can't replace node
        } else {
          nearNode = ele;
          near.push(ele);
        }
      }
      if (ele.isEdge() && (sqDist == null || sqDist < minSqDist)) {
        if (nearEdge) {
          // then replace existing edge
          // can replace only if same z-index
          if (nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value && nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value) {
            for (var i = 0; i < near.length; i++) {
              if (near[i].isEdge()) {
                near[i] = ele;
                nearEdge = ele;
                minSqDist = sqDist != null ? sqDist : minSqDist;
                break;
              }
            }
          }
        } else {
          near.push(ele);
          nearEdge = ele;
          minSqDist = sqDist != null ? sqDist : minSqDist;
        }
      }
    }
    function checkNode(node) {
      var width = node.outerWidth() + 2 * nodeThreshold;
      var height = node.outerHeight() + 2 * nodeThreshold;
      var hw = width / 2;
      var hh = height / 2;
      var pos = node.position();
      if (pos.x - hw <= x && x <= pos.x + hw // bb check x
      && pos.y - hh <= y && y <= pos.y + hh // bb check y
      ) {
        var shape = r.nodeShapes[self.getNodeShape(node)];
        if (shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)) {
          addEle(node, 0);
          return true;
        }
      }
    }
    function checkEdge(edge) {
      var _p = edge._private;
      var rs = _p.rscratch;
      var styleWidth = edge.pstyle('width').pfValue;
      var scale = edge.pstyle('arrow-scale').value;
      var width = styleWidth / 2 + edgeThreshold; // more like a distance radius from centre
      var widthSq = width * width;
      var width2 = width * 2;
      var src = _p.source;
      var tgt = _p.target;
      var sqDist;
      if (rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack') {
        var pts = rs.allpts;
        for (var i = 0; i + 3 < pts.length; i += 2) {
          if (inLineVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], width2) && widthSq > (sqDist = sqdistToFiniteLine(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3]))) {
            addEle(edge, sqDist);
            return true;
          }
        }
      } else if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {
        var pts = rs.allpts;
        for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
          if (inBezierVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], width2) && widthSq > (sqDist = sqdistToQuadraticBezier(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]))) {
            addEle(edge, sqDist);
            return true;
          }
        }
      }

      // if we're close to the edge but didn't hit it, maybe we hit its arrows

      var src = src || _p.source;
      var tgt = tgt || _p.target;
      var arSize = self.getArrowWidth(styleWidth, scale);
      var arrows = [{
        name: 'source',
        x: rs.arrowStartX,
        y: rs.arrowStartY,
        angle: rs.srcArrowAngle
      }, {
        name: 'target',
        x: rs.arrowEndX,
        y: rs.arrowEndY,
        angle: rs.tgtArrowAngle
      }, {
        name: 'mid-source',
        x: rs.midX,
        y: rs.midY,
        angle: rs.midsrcArrowAngle
      }, {
        name: 'mid-target',
        x: rs.midX,
        y: rs.midY,
        angle: rs.midtgtArrowAngle
      }];
      for (var i = 0; i < arrows.length; i++) {
        var ar = arrows[i];
        var shape = r.arrowShapes[edge.pstyle(ar.name + '-arrow-shape').value];
        var edgeWidth = edge.pstyle('width').pfValue;
        if (shape.roughCollide(x, y, arSize, ar.angle, {
          x: ar.x,
          y: ar.y
        }, edgeWidth, edgeThreshold) && shape.collide(x, y, arSize, ar.angle, {
          x: ar.x,
          y: ar.y
        }, edgeWidth, edgeThreshold)) {
          addEle(edge);
          return true;
        }
      }

      // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)
      if (hasCompounds && near.length > 0) {
        checkNode(src);
        checkNode(tgt);
      }
    }
    function preprop(obj, name, pre) {
      return getPrefixedProperty(obj, name, pre);
    }
    function checkLabel(ele, prefix) {
      var _p = ele._private;
      var th = labelThreshold;
      var prefixDash;
      if (prefix) {
        prefixDash = prefix + '-';
      } else {
        prefixDash = '';
      }
      ele.boundingBox();
      var bb = _p.labelBounds[prefix || 'main'];
      var text = ele.pstyle(prefixDash + 'label').value;
      var eventsEnabled = ele.pstyle('text-events').strValue === 'yes';
      if (!eventsEnabled || !text) {
        return;
      }
      var lx = preprop(_p.rscratch, 'labelX', prefix);
      var ly = preprop(_p.rscratch, 'labelY', prefix);
      var theta = preprop(_p.rscratch, 'labelAngle', prefix);
      var ox = ele.pstyle(prefixDash + 'text-margin-x').pfValue;
      var oy = ele.pstyle(prefixDash + 'text-margin-y').pfValue;
      var lx1 = bb.x1 - th - ox; // (-ox, -oy) as bb already includes margin
      var lx2 = bb.x2 + th - ox; // and rotation is about (lx, ly)
      var ly1 = bb.y1 - th - oy;
      var ly2 = bb.y2 + th - oy;
      if (theta) {
        var cos = Math.cos(theta);
        var sin = Math.sin(theta);
        var rotate = function rotate(x, y) {
          x = x - lx;
          y = y - ly;
          return {
            x: x * cos - y * sin + lx,
            y: x * sin + y * cos + ly
          };
        };
        var px1y1 = rotate(lx1, ly1);
        var px1y2 = rotate(lx1, ly2);
        var px2y1 = rotate(lx2, ly1);
        var px2y2 = rotate(lx2, ly2);
        var points = [
        // with the margin added after the rotation is applied
        px1y1.x + ox, px1y1.y + oy, px2y1.x + ox, px2y1.y + oy, px2y2.x + ox, px2y2.y + oy, px1y2.x + ox, px1y2.y + oy];
        if (pointInsidePolygonPoints(x, y, points)) {
          addEle(ele);
          return true;
        }
      } else {
        // do a cheaper bb check
        if (inBoundingBox(bb, x, y)) {
          addEle(ele);
          return true;
        }
      }
    }
    for (var i = eles.length - 1; i >= 0; i--) {
      // reverse order for precedence
      var ele = eles[i];
      if (ele.isNode()) {
        checkNode(ele) || checkLabel(ele);
      } else {
        // then edge
        checkEdge(ele) || checkLabel(ele) || checkLabel(ele, 'source') || checkLabel(ele, 'target');
      }
    }
    return near;
  };

  // 'Give me everything from this box'
  BRp$e.getAllInBox = function (x1, y1, x2, y2) {
    var eles = this.getCachedZSortedEles().interactive;
    var box = [];
    var x1c = Math.min(x1, x2);
    var x2c = Math.max(x1, x2);
    var y1c = Math.min(y1, y2);
    var y2c = Math.max(y1, y2);
    x1 = x1c;
    x2 = x2c;
    y1 = y1c;
    y2 = y2c;
    var boxBb = makeBoundingBox({
      x1: x1,
      y1: y1,
      x2: x2,
      y2: y2
    });
    for (var e = 0; e < eles.length; e++) {
      var ele = eles[e];
      if (ele.isNode()) {
        var node = ele;
        var nodeBb = node.boundingBox({
          includeNodes: true,
          includeEdges: false,
          includeLabels: false
        });
        if (boundingBoxesIntersect(boxBb, nodeBb) && !boundingBoxInBoundingBox(nodeBb, boxBb)) {
          box.push(node);
        }
      } else {
        var edge = ele;
        var _p = edge._private;
        var rs = _p.rscratch;
        if (rs.startX != null && rs.startY != null && !inBoundingBox(boxBb, rs.startX, rs.startY)) {
          continue;
        }
        if (rs.endX != null && rs.endY != null && !inBoundingBox(boxBb, rs.endX, rs.endY)) {
          continue;
        }
        if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack') {
          var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts;
          var allInside = true;
          for (var i = 0; i < pts.length; i++) {
            if (!pointInBoundingBox(boxBb, pts[i])) {
              allInside = false;
              break;
            }
          }
          if (allInside) {
            box.push(edge);
          }
        } else if (rs.edgeType === 'haystack' || rs.edgeType === 'straight') {
          box.push(edge);
        }
      }
    }
    return box;
  };

  var BRp$d = {};
  BRp$d.calculateArrowAngles = function (edge) {
    var rs = edge._private.rscratch;
    var isHaystack = rs.edgeType === 'haystack';
    var isBezier = rs.edgeType === 'bezier';
    var isMultibezier = rs.edgeType === 'multibezier';
    var isSegments = rs.edgeType === 'segments';
    var isCompound = rs.edgeType === 'compound';
    var isSelf = rs.edgeType === 'self';

    // Displacement gives direction for arrowhead orientation
    var dispX, dispY;
    var startX, startY, endX, endY, midX, midY;
    if (isHaystack) {
      startX = rs.haystackPts[0];
      startY = rs.haystackPts[1];
      endX = rs.haystackPts[2];
      endY = rs.haystackPts[3];
    } else {
      startX = rs.arrowStartX;
      startY = rs.arrowStartY;
      endX = rs.arrowEndX;
      endY = rs.arrowEndY;
    }
    midX = rs.midX;
    midY = rs.midY;

    // source
    //

    if (isSegments) {
      dispX = startX - rs.segpts[0];
      dispY = startY - rs.segpts[1];
    } else if (isMultibezier || isCompound || isSelf || isBezier) {
      var pts = rs.allpts;
      var bX = qbezierAt(pts[0], pts[2], pts[4], 0.1);
      var bY = qbezierAt(pts[1], pts[3], pts[5], 0.1);
      dispX = startX - bX;
      dispY = startY - bY;
    } else {
      dispX = startX - midX;
      dispY = startY - midY;
    }
    rs.srcArrowAngle = getAngleFromDisp(dispX, dispY);

    // mid target
    //

    var midX = rs.midX;
    var midY = rs.midY;
    if (isHaystack) {
      midX = (startX + endX) / 2;
      midY = (startY + endY) / 2;
    }
    dispX = endX - startX;
    dispY = endY - startY;
    if (isSegments) {
      var pts = rs.allpts;
      if (pts.length / 2 % 2 === 0) {
        var i2 = pts.length / 2;
        var i1 = i2 - 2;
        dispX = pts[i2] - pts[i1];
        dispY = pts[i2 + 1] - pts[i1 + 1];
      } else {
        var i2 = pts.length / 2 - 1;
        var i1 = i2 - 2;
        var i3 = i2 + 2;
        dispX = pts[i2] - pts[i1];
        dispY = pts[i2 + 1] - pts[i1 + 1];
      }
    } else if (isMultibezier || isCompound || isSelf) {
      var pts = rs.allpts;
      var cpts = rs.ctrlpts;
      var bp0x, bp0y;
      var bp1x, bp1y;
      if (cpts.length / 2 % 2 === 0) {
        var p0 = pts.length / 2 - 1; // startpt
        var ic = p0 + 2;
        var p1 = ic + 2;
        bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0);
        bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0);
        bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0001);
        bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0001);
      } else {
        var ic = pts.length / 2 - 1; // ctrpt
        var p0 = ic - 2; // startpt
        var p1 = ic + 2; // endpt

        bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.4999);
        bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.4999);
        bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.5);
        bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.5);
      }
      dispX = bp1x - bp0x;
      dispY = bp1y - bp0y;
    }
    rs.midtgtArrowAngle = getAngleFromDisp(dispX, dispY);
    rs.midDispX = dispX;
    rs.midDispY = dispY;

    // mid source
    //

    dispX *= -1;
    dispY *= -1;
    if (isSegments) {
      var pts = rs.allpts;
      if (pts.length / 2 % 2 === 0) ; else {
        var i2 = pts.length / 2 - 1;
        var i3 = i2 + 2;
        dispX = -(pts[i3] - pts[i2]);
        dispY = -(pts[i3 + 1] - pts[i2 + 1]);
      }
    }
    rs.midsrcArrowAngle = getAngleFromDisp(dispX, dispY);

    // target
    //

    if (isSegments) {
      dispX = endX - rs.segpts[rs.segpts.length - 2];
      dispY = endY - rs.segpts[rs.segpts.length - 1];
    } else if (isMultibezier || isCompound || isSelf || isBezier) {
      var pts = rs.allpts;
      var l = pts.length;
      var bX = qbezierAt(pts[l - 6], pts[l - 4], pts[l - 2], 0.9);
      var bY = qbezierAt(pts[l - 5], pts[l - 3], pts[l - 1], 0.9);
      dispX = endX - bX;
      dispY = endY - bY;
    } else {
      dispX = endX - midX;
      dispY = endY - midY;
    }
    rs.tgtArrowAngle = getAngleFromDisp(dispX, dispY);
  };
  BRp$d.getArrowWidth = BRp$d.getArrowHeight = function (edgeWidth, scale) {
    var cache = this.arrowWidthCache = this.arrowWidthCache || {};
    var cachedVal = cache[edgeWidth + ', ' + scale];
    if (cachedVal) {
      return cachedVal;
    }
    cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29) * scale;
    cache[edgeWidth + ', ' + scale] = cachedVal;
    return cachedVal;
  };

  var BRp$c = {};
  BRp$c.findMidptPtsEtc = function (edge, pairInfo) {
    var posPts = pairInfo.posPts,
      intersectionPts = pairInfo.intersectionPts,
      vectorNormInverse = pairInfo.vectorNormInverse;
    var midptPts;

    // n.b. assumes all edges in bezier bundle have same endpoints specified
    var srcManEndpt = edge.pstyle('source-endpoint');
    var tgtManEndpt = edge.pstyle('target-endpoint');
    var haveManualEndPts = srcManEndpt.units != null && tgtManEndpt.units != null;
    var recalcVectorNormInverse = function recalcVectorNormInverse(x1, y1, x2, y2) {
      var dy = y2 - y1;
      var dx = x2 - x1;
      var l = Math.sqrt(dx * dx + dy * dy);
      return {
        x: -dy / l,
        y: dx / l
      };
    };
    var edgeDistances = edge.pstyle('edge-distances').value;
    switch (edgeDistances) {
      case 'node-position':
        midptPts = posPts;
        break;
      case 'intersection':
        midptPts = intersectionPts;
        break;
      case 'endpoints':
        {
          if (haveManualEndPts) {
            var _this$manualEndptToPx = this.manualEndptToPx(edge.source()[0], srcManEndpt),
              _this$manualEndptToPx2 = _slicedToArray(_this$manualEndptToPx, 2),
              x1 = _this$manualEndptToPx2[0],
              y1 = _this$manualEndptToPx2[1];
            var _this$manualEndptToPx3 = this.manualEndptToPx(edge.target()[0], tgtManEndpt),
              _this$manualEndptToPx4 = _slicedToArray(_this$manualEndptToPx3, 2),
              x2 = _this$manualEndptToPx4[0],
              y2 = _this$manualEndptToPx4[1];
            var endPts = {
              x1: x1,
              y1: y1,
              x2: x2,
              y2: y2
            };
            vectorNormInverse = recalcVectorNormInverse(x1, y1, x2, y2);
            midptPts = endPts;
          } else {
            warn("Edge ".concat(edge.id(), " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint.  Falling back on edge-distances:intersection (default)."));
            midptPts = intersectionPts; // back to default
          }

          break;
        }
    }
    return {
      midptPts: midptPts,
      vectorNormInverse: vectorNormInverse
    };
  };
  BRp$c.findHaystackPoints = function (edges) {
    for (var i = 0; i < edges.length; i++) {
      var edge = edges[i];
      var _p = edge._private;
      var rs = _p.rscratch;
      if (!rs.haystack) {
        var angle = Math.random() * 2 * Math.PI;
        rs.source = {
          x: Math.cos(angle),
          y: Math.sin(angle)
        };
        angle = Math.random() * 2 * Math.PI;
        rs.target = {
          x: Math.cos(angle),
          y: Math.sin(angle)
        };
      }
      var src = _p.source;
      var tgt = _p.target;
      var srcPos = src.position();
      var tgtPos = tgt.position();
      var srcW = src.width();
      var tgtW = tgt.width();
      var srcH = src.height();
      var tgtH = tgt.height();
      var radius = edge.pstyle('haystack-radius').value;
      var halfRadius = radius / 2; // b/c have to half width/height

      rs.haystackPts = rs.allpts = [rs.source.x * srcW * halfRadius + srcPos.x, rs.source.y * srcH * halfRadius + srcPos.y, rs.target.x * tgtW * halfRadius + tgtPos.x, rs.target.y * tgtH * halfRadius + tgtPos.y];
      rs.midX = (rs.allpts[0] + rs.allpts[2]) / 2;
      rs.midY = (rs.allpts[1] + rs.allpts[3]) / 2;

      // always override as haystack in case set to different type previously
      rs.edgeType = 'haystack';
      rs.haystack = true;
      this.storeEdgeProjections(edge);
      this.calculateArrowAngles(edge);
      this.recalculateEdgeLabelProjections(edge);
      this.calculateLabelAngles(edge);
    }
  };
  BRp$c.findSegmentsPoints = function (edge, pairInfo) {
    // Segments (multiple straight lines)

    var rs = edge._private.rscratch;
    var segmentWs = edge.pstyle('segment-weights');
    var segmentDs = edge.pstyle('segment-distances');
    var segmentsN = Math.min(segmentWs.pfValue.length, segmentDs.pfValue.length);
    rs.edgeType = 'segments';
    rs.segpts = [];
    for (var s = 0; s < segmentsN; s++) {
      var w = segmentWs.pfValue[s];
      var d = segmentDs.pfValue[s];
      var w1 = 1 - w;
      var w2 = w;
      var _this$findMidptPtsEtc = this.findMidptPtsEtc(edge, pairInfo),
        midptPts = _this$findMidptPtsEtc.midptPts,
        vectorNormInverse = _this$findMidptPtsEtc.vectorNormInverse;
      var adjustedMidpt = {
        x: midptPts.x1 * w1 + midptPts.x2 * w2,
        y: midptPts.y1 * w1 + midptPts.y2 * w2
      };
      rs.segpts.push(adjustedMidpt.x + vectorNormInverse.x * d, adjustedMidpt.y + vectorNormInverse.y * d);
    }
  };
  BRp$c.findLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {
    // Self-edge

    var rs = edge._private.rscratch;
    var dirCounts = pairInfo.dirCounts,
      srcPos = pairInfo.srcPos;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var loopDir = edge.pstyle('loop-direction').pfValue;
    var loopSwp = edge.pstyle('loop-sweep').pfValue;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    rs.edgeType = 'self';
    var j = i;
    var loopDist = stepSize;
    if (edgeIsUnbundled) {
      j = 0;
      loopDist = ctrlptDist;
    }
    var loopAngle = loopDir - Math.PI / 2;
    var outAngle = loopAngle - loopSwp / 2;
    var inAngle = loopAngle + loopSwp / 2;

    // increase by step size for overlapping loops, keyed on direction and sweep values
    var dc = String(loopDir + '_' + loopSwp);
    j = dirCounts[dc] === undefined ? dirCounts[dc] = 0 : ++dirCounts[dc];
    rs.ctrlpts = [srcPos.x + Math.cos(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.x + Math.cos(inAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(inAngle) * 1.4 * loopDist * (j / 3 + 1)];
  };
  BRp$c.findCompoundLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {
    // Compound edge

    var rs = edge._private.rscratch;
    rs.edgeType = 'compound';
    var srcPos = pairInfo.srcPos,
      tgtPos = pairInfo.tgtPos,
      srcW = pairInfo.srcW,
      srcH = pairInfo.srcH,
      tgtW = pairInfo.tgtW,
      tgtH = pairInfo.tgtH;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var j = i;
    var loopDist = stepSize;
    if (edgeIsUnbundled) {
      j = 0;
      loopDist = ctrlptDist;
    }
    var loopW = 50;
    var loopaPos = {
      x: srcPos.x - srcW / 2,
      y: srcPos.y - srcH / 2
    };
    var loopbPos = {
      x: tgtPos.x - tgtW / 2,
      y: tgtPos.y - tgtH / 2
    };
    var loopPos = {
      x: Math.min(loopaPos.x, loopbPos.x),
      y: Math.min(loopaPos.y, loopbPos.y)
    };

    // avoids cases with impossible beziers
    var minCompoundStretch = 0.5;
    var compoundStretchA = Math.max(minCompoundStretch, Math.log(srcW * 0.01));
    var compoundStretchB = Math.max(minCompoundStretch, Math.log(tgtW * 0.01));
    rs.ctrlpts = [loopPos.x, loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA, loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB, loopPos.y];
  };
  BRp$c.findStraightEdgePoints = function (edge) {
    // Straight edge within bundle

    edge._private.rscratch.edgeType = 'straight';
  };
  BRp$c.findBezierPoints = function (edge, pairInfo, i, edgeIsUnbundled, edgeIsSwapped) {
    var rs = edge._private.rscratch;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptWs = edge.pstyle('control-point-weights');
    var bezierN = ctrlptDists && ctrlptWs ? Math.min(ctrlptDists.value.length, ctrlptWs.value.length) : 1;
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var ctrlptWeight = ctrlptWs.value[0];

    // (Multi)bezier

    var multi = edgeIsUnbundled;
    rs.edgeType = multi ? 'multibezier' : 'bezier';
    rs.ctrlpts = [];
    for (var b = 0; b < bezierN; b++) {
      var normctrlptDist = (0.5 - pairInfo.eles.length / 2 + i) * stepSize * (edgeIsSwapped ? -1 : 1);
      var manctrlptDist = void 0;
      var sign = signum(normctrlptDist);
      if (multi) {
        ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size
        ctrlptWeight = ctrlptWs.value[b];
      }
      if (edgeIsUnbundled) {
        // multi or single unbundled
        manctrlptDist = ctrlptDist;
      } else {
        manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined;
      }
      var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist;
      var w1 = 1 - ctrlptWeight;
      var w2 = ctrlptWeight;
      var _this$findMidptPtsEtc2 = this.findMidptPtsEtc(edge, pairInfo),
        midptPts = _this$findMidptPtsEtc2.midptPts,
        vectorNormInverse = _this$findMidptPtsEtc2.vectorNormInverse;
      var adjustedMidpt = {
        x: midptPts.x1 * w1 + midptPts.x2 * w2,
        y: midptPts.y1 * w1 + midptPts.y2 * w2
      };
      rs.ctrlpts.push(adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint);
    }
  };
  BRp$c.findTaxiPoints = function (edge, pairInfo) {
    // Taxicab geometry with two turns maximum

    var rs = edge._private.rscratch;
    rs.edgeType = 'segments';
    var VERTICAL = 'vertical';
    var HORIZONTAL = 'horizontal';
    var LEFTWARD = 'leftward';
    var RIGHTWARD = 'rightward';
    var DOWNWARD = 'downward';
    var UPWARD = 'upward';
    var AUTO = 'auto';
    var posPts = pairInfo.posPts,
      srcW = pairInfo.srcW,
      srcH = pairInfo.srcH,
      tgtW = pairInfo.tgtW,
      tgtH = pairInfo.tgtH;
    var edgeDistances = edge.pstyle('edge-distances').value;
    var dIncludesNodeBody = edgeDistances !== 'node-position';
    var taxiDir = edge.pstyle('taxi-direction').value;
    var rawTaxiDir = taxiDir; // unprocessed value
    var taxiTurn = edge.pstyle('taxi-turn');
    var turnIsPercent = taxiTurn.units === '%';
    var taxiTurnPfVal = taxiTurn.pfValue;
    var turnIsNegative = taxiTurnPfVal < 0; // i.e. from target side
    var minD = edge.pstyle('taxi-turn-min-distance').pfValue;
    var dw = dIncludesNodeBody ? (srcW + tgtW) / 2 : 0;
    var dh = dIncludesNodeBody ? (srcH + tgtH) / 2 : 0;
    var pdx = posPts.x2 - posPts.x1;
    var pdy = posPts.y2 - posPts.y1;

    // take away the effective w/h from the magnitude of the delta value
    var subDWH = function subDWH(dxy, dwh) {
      if (dxy > 0) {
        return Math.max(dxy - dwh, 0);
      } else {
        return Math.min(dxy + dwh, 0);
      }
    };
    var dx = subDWH(pdx, dw);
    var dy = subDWH(pdy, dh);
    var isExplicitDir = false;
    if (rawTaxiDir === AUTO) {
      taxiDir = Math.abs(dx) > Math.abs(dy) ? HORIZONTAL : VERTICAL;
    } else if (rawTaxiDir === UPWARD || rawTaxiDir === DOWNWARD) {
      taxiDir = VERTICAL;
      isExplicitDir = true;
    } else if (rawTaxiDir === LEFTWARD || rawTaxiDir === RIGHTWARD) {
      taxiDir = HORIZONTAL;
      isExplicitDir = true;
    }
    var isVert = taxiDir === VERTICAL;
    var l = isVert ? dy : dx;
    var pl = isVert ? pdy : pdx;
    var sgnL = signum(pl);
    var forcedDir = false;
    if (!(isExplicitDir && (turnIsPercent || turnIsNegative)) // forcing in this case would cause weird growing in the opposite direction
    && (rawTaxiDir === DOWNWARD && pl < 0 || rawTaxiDir === UPWARD && pl > 0 || rawTaxiDir === LEFTWARD && pl > 0 || rawTaxiDir === RIGHTWARD && pl < 0)) {
      sgnL *= -1;
      l = sgnL * Math.abs(l);
      forcedDir = true;
    }
    var d;
    if (turnIsPercent) {
      var p = taxiTurnPfVal < 0 ? 1 + taxiTurnPfVal : taxiTurnPfVal;
      d = p * l;
    } else {
      var k = taxiTurnPfVal < 0 ? l : 0;
      d = k + taxiTurnPfVal * sgnL;
    }
    var getIsTooClose = function getIsTooClose(d) {
      return Math.abs(d) < minD || Math.abs(d) >= Math.abs(l);
    };
    var isTooCloseSrc = getIsTooClose(d);
    var isTooCloseTgt = getIsTooClose(Math.abs(l) - Math.abs(d));
    var isTooClose = isTooCloseSrc || isTooCloseTgt;
    if (isTooClose && !forcedDir) {
      // non-ideal routing
      if (isVert) {
        // vertical fallbacks
        var lShapeInsideSrc = Math.abs(pl) <= srcH / 2;
        var lShapeInsideTgt = Math.abs(pdx) <= tgtW / 2;
        if (lShapeInsideSrc) {
          // horizontal Z-shape (direction not respected)
          var x = (posPts.x1 + posPts.x2) / 2;
          var y1 = posPts.y1,
            y2 = posPts.y2;
          rs.segpts = [x, y1, x, y2];
        } else if (lShapeInsideTgt) {
          // vertical Z-shape (distance not respected)
          var y = (posPts.y1 + posPts.y2) / 2;
          var x1 = posPts.x1,
            x2 = posPts.x2;
          rs.segpts = [x1, y, x2, y];
        } else {
          // L-shape fallback (turn distance not respected, but works well with tree siblings)
          rs.segpts = [posPts.x1, posPts.y2];
        }
      } else {
        // horizontal fallbacks
        var _lShapeInsideSrc = Math.abs(pl) <= srcW / 2;
        var _lShapeInsideTgt = Math.abs(pdy) <= tgtH / 2;
        if (_lShapeInsideSrc) {
          // vertical Z-shape (direction not respected)
          var _y = (posPts.y1 + posPts.y2) / 2;
          var _x = posPts.x1,
            _x2 = posPts.x2;
          rs.segpts = [_x, _y, _x2, _y];
        } else if (_lShapeInsideTgt) {
          // horizontal Z-shape (turn distance not respected)
          var _x3 = (posPts.x1 + posPts.x2) / 2;
          var _y2 = posPts.y1,
            _y3 = posPts.y2;
          rs.segpts = [_x3, _y2, _x3, _y3];
        } else {
          // L-shape (turn distance not respected, but works well for tree siblings)
          rs.segpts = [posPts.x2, posPts.y1];
        }
      }
    } else {
      // ideal routing
      if (isVert) {
        var _y4 = posPts.y1 + d + (dIncludesNodeBody ? srcH / 2 * sgnL : 0);
        var _x4 = posPts.x1,
          _x5 = posPts.x2;
        rs.segpts = [_x4, _y4, _x5, _y4];
      } else {
        // horizontal
        var _x6 = posPts.x1 + d + (dIncludesNodeBody ? srcW / 2 * sgnL : 0);
        var _y5 = posPts.y1,
          _y6 = posPts.y2;
        rs.segpts = [_x6, _y5, _x6, _y6];
      }
    }
  };
  BRp$c.tryToCorrectInvalidPoints = function (edge, pairInfo) {
    var rs = edge._private.rscratch;

    // can only correct beziers for now...
    if (rs.edgeType === 'bezier') {
      var srcPos = pairInfo.srcPos,
        tgtPos = pairInfo.tgtPos,
        srcW = pairInfo.srcW,
        srcH = pairInfo.srcH,
        tgtW = pairInfo.tgtW,
        tgtH = pairInfo.tgtH,
        srcShape = pairInfo.srcShape,
        tgtShape = pairInfo.tgtShape;
      var badStart = !number$1(rs.startX) || !number$1(rs.startY);
      var badAStart = !number$1(rs.arrowStartX) || !number$1(rs.arrowStartY);
      var badEnd = !number$1(rs.endX) || !number$1(rs.endY);
      var badAEnd = !number$1(rs.arrowEndX) || !number$1(rs.arrowEndY);
      var minCpADistFactor = 3;
      var arrowW = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;
      var minCpADist = minCpADistFactor * arrowW;
      var startACpDist = dist({
        x: rs.ctrlpts[0],
        y: rs.ctrlpts[1]
      }, {
        x: rs.startX,
        y: rs.startY
      });
      var closeStartACp = startACpDist < minCpADist;
      var endACpDist = dist({
        x: rs.ctrlpts[0],
        y: rs.ctrlpts[1]
      }, {
        x: rs.endX,
        y: rs.endY
      });
      var closeEndACp = endACpDist < minCpADist;
      var overlapping = false;
      if (badStart || badAStart || closeStartACp) {
        overlapping = true;

        // project control point along line from src centre to outside the src shape
        // (otherwise intersection will yield nothing)
        var cpD = {
          // delta
          x: rs.ctrlpts[0] - srcPos.x,
          y: rs.ctrlpts[1] - srcPos.y
        };
        var cpL = Math.sqrt(cpD.x * cpD.x + cpD.y * cpD.y); // length of line
        var cpM = {
          // normalised delta
          x: cpD.x / cpL,
          y: cpD.y / cpL
        };
        var radius = Math.max(srcW, srcH);
        var cpProj = {
          // *2 radius guarantees outside shape
          x: rs.ctrlpts[0] + cpM.x * 2 * radius,
          y: rs.ctrlpts[1] + cpM.y * 2 * radius
        };
        var srcCtrlPtIntn = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, cpProj.x, cpProj.y, 0);
        if (closeStartACp) {
          rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist);
          rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist);
        } else {
          rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist;
          rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist;
        }
      }
      if (badEnd || badAEnd || closeEndACp) {
        overlapping = true;

        // project control point along line from tgt centre to outside the tgt shape
        // (otherwise intersection will yield nothing)
        var _cpD = {
          // delta
          x: rs.ctrlpts[0] - tgtPos.x,
          y: rs.ctrlpts[1] - tgtPos.y
        };
        var _cpL = Math.sqrt(_cpD.x * _cpD.x + _cpD.y * _cpD.y); // length of line
        var _cpM = {
          // normalised delta
          x: _cpD.x / _cpL,
          y: _cpD.y / _cpL
        };
        var _radius = Math.max(srcW, srcH);
        var _cpProj = {
          // *2 radius guarantees outside shape
          x: rs.ctrlpts[0] + _cpM.x * 2 * _radius,
          y: rs.ctrlpts[1] + _cpM.y * 2 * _radius
        };
        var tgtCtrlPtIntn = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, _cpProj.x, _cpProj.y, 0);
        if (closeEndACp) {
          rs.ctrlpts[0] = rs.ctrlpts[0] + _cpM.x * (minCpADist - endACpDist);
          rs.ctrlpts[1] = rs.ctrlpts[1] + _cpM.y * (minCpADist - endACpDist);
        } else {
          rs.ctrlpts[0] = tgtCtrlPtIntn[0] + _cpM.x * minCpADist;
          rs.ctrlpts[1] = tgtCtrlPtIntn[1] + _cpM.y * minCpADist;
        }
      }
      if (overlapping) {
        // recalc endpts
        this.findEndpoints(edge);
      }
    }
  };
  BRp$c.storeAllpts = function (edge) {
    var rs = edge._private.rscratch;
    if (rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {
      rs.allpts = [];
      rs.allpts.push(rs.startX, rs.startY);
      for (var b = 0; b + 1 < rs.ctrlpts.length; b += 2) {
        // ctrl pt itself
        rs.allpts.push(rs.ctrlpts[b], rs.ctrlpts[b + 1]);

        // the midpt between ctrlpts as intermediate destination pts
        if (b + 3 < rs.ctrlpts.length) {
          rs.allpts.push((rs.ctrlpts[b] + rs.ctrlpts[b + 2]) / 2, (rs.ctrlpts[b + 1] + rs.ctrlpts[b + 3]) / 2);
        }
      }
      rs.allpts.push(rs.endX, rs.endY);
      var m, mt;
      if (rs.ctrlpts.length / 2 % 2 === 0) {
        m = rs.allpts.length / 2 - 1;
        rs.midX = rs.allpts[m];
        rs.midY = rs.allpts[m + 1];
      } else {
        m = rs.allpts.length / 2 - 3;
        mt = 0.5;
        rs.midX = qbezierAt(rs.allpts[m], rs.allpts[m + 2], rs.allpts[m + 4], mt);
        rs.midY = qbezierAt(rs.allpts[m + 1], rs.allpts[m + 3], rs.allpts[m + 5], mt);
      }
    } else if (rs.edgeType === 'straight') {
      // need to calc these after endpts
      rs.allpts = [rs.startX, rs.startY, rs.endX, rs.endY];

      // default midpt for labels etc
      rs.midX = (rs.startX + rs.endX + rs.arrowStartX + rs.arrowEndX) / 4;
      rs.midY = (rs.startY + rs.endY + rs.arrowStartY + rs.arrowEndY) / 4;
    } else if (rs.edgeType === 'segments') {
      rs.allpts = [];
      rs.allpts.push(rs.startX, rs.startY);
      rs.allpts.push.apply(rs.allpts, rs.segpts);
      rs.allpts.push(rs.endX, rs.endY);
      if (rs.segpts.length % 4 === 0) {
        var i2 = rs.segpts.length / 2;
        var i1 = i2 - 2;
        rs.midX = (rs.segpts[i1] + rs.segpts[i2]) / 2;
        rs.midY = (rs.segpts[i1 + 1] + rs.segpts[i2 + 1]) / 2;
      } else {
        var _i = rs.segpts.length / 2 - 1;
        rs.midX = rs.segpts[_i];
        rs.midY = rs.segpts[_i + 1];
      }
    }
  };
  BRp$c.checkForInvalidEdgeWarning = function (edge) {
    var rs = edge[0]._private.rscratch;
    if (rs.nodesOverlap || number$1(rs.startX) && number$1(rs.startY) && number$1(rs.endX) && number$1(rs.endY)) {
      rs.loggedErr = false;
    } else {
      if (!rs.loggedErr) {
        rs.loggedErr = true;
        warn('Edge `' + edge.id() + '` has invalid endpoints and so it is impossible to draw.  Adjust your edge style (e.g. control points) accordingly or use an alternative edge type.  This is expected behaviour when the source node and the target node overlap.');
      }
    }
  };
  BRp$c.findEdgeControlPoints = function (edges) {
    var _this = this;
    if (!edges || edges.length === 0) {
      return;
    }
    var r = this;
    var cy = r.cy;
    var hasCompounds = cy.hasCompoundNodes();
    var hashTable = {
      map: new Map$2(),
      get: function get(pairId) {
        var map2 = this.map.get(pairId[0]);
        if (map2 != null) {
          return map2.get(pairId[1]);
        } else {
          return null;
        }
      },
      set: function set(pairId, val) {
        var map2 = this.map.get(pairId[0]);
        if (map2 == null) {
          map2 = new Map$2();
          this.map.set(pairId[0], map2);
        }
        map2.set(pairId[1], val);
      }
    };
    var pairIds = [];
    var haystackEdges = [];

    // create a table of edge (src, tgt) => list of edges between them
    for (var i = 0; i < edges.length; i++) {
      var edge = edges[i];
      var _p = edge._private;
      var curveStyle = edge.pstyle('curve-style').value;

      // ignore edges who are not to be displayed
      // they shouldn't take up space
      if (edge.removed() || !edge.takesUpSpace()) {
        continue;
      }
      if (curveStyle === 'haystack') {
        haystackEdges.push(edge);
        continue;
      }
      var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'straight' || curveStyle === 'straight-triangle' || curveStyle === 'taxi';
      var edgeIsBezier = curveStyle === 'unbundled-bezier' || curveStyle === 'bezier';
      var src = _p.source;
      var tgt = _p.target;
      var srcIndex = src.poolIndex();
      var tgtIndex = tgt.poolIndex();
      var pairId = [srcIndex, tgtIndex].sort();
      var tableEntry = hashTable.get(pairId);
      if (tableEntry == null) {
        tableEntry = {
          eles: []
        };
        hashTable.set(pairId, tableEntry);
        pairIds.push(pairId);
      }
      tableEntry.eles.push(edge);
      if (edgeIsUnbundled) {
        tableEntry.hasUnbundled = true;
      }
      if (edgeIsBezier) {
        tableEntry.hasBezier = true;
      }
    }

    // for each pair (src, tgt), create the ctrl pts
    // Nested for loop is OK; total number of iterations for both loops = edgeCount
    var _loop = function _loop(p) {
      var pairId = pairIds[p];
      var pairInfo = hashTable.get(pairId);
      var swappedpairInfo = void 0;
      if (!pairInfo.hasUnbundled) {
        var pllEdges = pairInfo.eles[0].parallelEdges().filter(function (e) {
          return e.isBundledBezier();
        });
        clearArray(pairInfo.eles);
        pllEdges.forEach(function (edge) {
          return pairInfo.eles.push(edge);
        });

        // for each pair id, the edges should be sorted by index
        pairInfo.eles.sort(function (edge1, edge2) {
          return edge1.poolIndex() - edge2.poolIndex();
        });
      }
      var firstEdge = pairInfo.eles[0];
      var src = firstEdge.source();
      var tgt = firstEdge.target();

      // make sure src/tgt distinction is consistent w.r.t. pairId
      if (src.poolIndex() > tgt.poolIndex()) {
        var temp = src;
        src = tgt;
        tgt = temp;
      }
      var srcPos = pairInfo.srcPos = src.position();
      var tgtPos = pairInfo.tgtPos = tgt.position();
      var srcW = pairInfo.srcW = src.outerWidth();
      var srcH = pairInfo.srcH = src.outerHeight();
      var tgtW = pairInfo.tgtW = tgt.outerWidth();
      var tgtH = pairInfo.tgtH = tgt.outerHeight();
      var srcShape = pairInfo.srcShape = r.nodeShapes[_this.getNodeShape(src)];
      var tgtShape = pairInfo.tgtShape = r.nodeShapes[_this.getNodeShape(tgt)];
      pairInfo.dirCounts = {
        'north': 0,
        'west': 0,
        'south': 0,
        'east': 0,
        'northwest': 0,
        'southwest': 0,
        'northeast': 0,
        'southeast': 0
      };
      for (var _i2 = 0; _i2 < pairInfo.eles.length; _i2++) {
        var _edge = pairInfo.eles[_i2];
        var rs = _edge[0]._private.rscratch;
        var _curveStyle = _edge.pstyle('curve-style').value;
        var _edgeIsUnbundled = _curveStyle === 'unbundled-bezier' || _curveStyle === 'segments' || _curveStyle === 'taxi';

        // whether the normalised pair order is the reverse of the edge's src-tgt order
        var edgeIsSwapped = !src.same(_edge.source());
        if (!pairInfo.calculatedIntersection && src !== tgt && (pairInfo.hasBezier || pairInfo.hasUnbundled)) {
          pairInfo.calculatedIntersection = true;

          // pt outside src shape to calc distance/displacement from src to tgt
          var srcOutside = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, tgtPos.x, tgtPos.y, 0);
          var srcIntn = pairInfo.srcIntn = srcOutside;

          // pt outside tgt shape to calc distance/displacement from src to tgt
          var tgtOutside = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, srcPos.x, srcPos.y, 0);
          var tgtIntn = pairInfo.tgtIntn = tgtOutside;
          var intersectionPts = pairInfo.intersectionPts = {
            x1: srcOutside[0],
            x2: tgtOutside[0],
            y1: srcOutside[1],
            y2: tgtOutside[1]
          };
          var posPts = pairInfo.posPts = {
            x1: srcPos.x,
            x2: tgtPos.x,
            y1: srcPos.y,
            y2: tgtPos.y
          };
          var dy = tgtOutside[1] - srcOutside[1];
          var dx = tgtOutside[0] - srcOutside[0];
          var l = Math.sqrt(dx * dx + dy * dy);
          var vector = pairInfo.vector = {
            x: dx,
            y: dy
          };
          var vectorNorm = pairInfo.vectorNorm = {
            x: vector.x / l,
            y: vector.y / l
          };
          var vectorNormInverse = {
            x: -vectorNorm.y,
            y: vectorNorm.x
          };

          // if node shapes overlap, then no ctrl pts to draw
          pairInfo.nodesOverlap = !number$1(l) || tgtShape.checkPoint(srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y) || srcShape.checkPoint(tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y);
          pairInfo.vectorNormInverse = vectorNormInverse;
          swappedpairInfo = {
            nodesOverlap: pairInfo.nodesOverlap,
            dirCounts: pairInfo.dirCounts,
            calculatedIntersection: true,
            hasBezier: pairInfo.hasBezier,
            hasUnbundled: pairInfo.hasUnbundled,
            eles: pairInfo.eles,
            srcPos: tgtPos,
            tgtPos: srcPos,
            srcW: tgtW,
            srcH: tgtH,
            tgtW: srcW,
            tgtH: srcH,
            srcIntn: tgtIntn,
            tgtIntn: srcIntn,
            srcShape: tgtShape,
            tgtShape: srcShape,
            posPts: {
              x1: posPts.x2,
              y1: posPts.y2,
              x2: posPts.x1,
              y2: posPts.y1
            },
            intersectionPts: {
              x1: intersectionPts.x2,
              y1: intersectionPts.y2,
              x2: intersectionPts.x1,
              y2: intersectionPts.y1
            },
            vector: {
              x: -vector.x,
              y: -vector.y
            },
            vectorNorm: {
              x: -vectorNorm.x,
              y: -vectorNorm.y
            },
            vectorNormInverse: {
              x: -vectorNormInverse.x,
              y: -vectorNormInverse.y
            }
          };
        }
        var passedPairInfo = edgeIsSwapped ? swappedpairInfo : pairInfo;
        rs.nodesOverlap = passedPairInfo.nodesOverlap;
        rs.srcIntn = passedPairInfo.srcIntn;
        rs.tgtIntn = passedPairInfo.tgtIntn;
        if (hasCompounds && (src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild()) && (src.parents().anySame(tgt) || tgt.parents().anySame(src) || src.same(tgt) && src.isParent())) {
          _this.findCompoundLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);
        } else if (src === tgt) {
          _this.findLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);
        } else if (_curveStyle === 'segments') {
          _this.findSegmentsPoints(_edge, passedPairInfo);
        } else if (_curveStyle === 'taxi') {
          _this.findTaxiPoints(_edge, passedPairInfo);
        } else if (_curveStyle === 'straight' || !_edgeIsUnbundled && pairInfo.eles.length % 2 === 1 && _i2 === Math.floor(pairInfo.eles.length / 2)) {
          _this.findStraightEdgePoints(_edge);
        } else {
          _this.findBezierPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled, edgeIsSwapped);
        }
        _this.findEndpoints(_edge);
        _this.tryToCorrectInvalidPoints(_edge, passedPairInfo);
        _this.checkForInvalidEdgeWarning(_edge);
        _this.storeAllpts(_edge);
        _this.storeEdgeProjections(_edge);
        _this.calculateArrowAngles(_edge);
        _this.recalculateEdgeLabelProjections(_edge);
        _this.calculateLabelAngles(_edge);
      } // for pair edges
    };
    for (var p = 0; p < pairIds.length; p++) {
      _loop(p);
    } // for pair ids

    // haystacks avoid the expense of pairInfo stuff (intersections etc.)
    this.findHaystackPoints(haystackEdges);
  };
  function getPts(pts) {
    var retPts = [];
    if (pts == null) {
      return;
    }
    for (var i = 0; i < pts.length; i += 2) {
      var x = pts[i];
      var y = pts[i + 1];
      retPts.push({
        x: x,
        y: y
      });
    }
    return retPts;
  }
  BRp$c.getSegmentPoints = function (edge) {
    var rs = edge[0]._private.rscratch;
    var type = rs.edgeType;
    if (type === 'segments') {
      this.recalculateRenderedStyle(edge);
      return getPts(rs.segpts);
    }
  };
  BRp$c.getControlPoints = function (edge) {
    var rs = edge[0]._private.rscratch;
    var type = rs.edgeType;
    if (type === 'bezier' || type === 'multibezier' || type === 'self' || type === 'compound') {
      this.recalculateRenderedStyle(edge);
      return getPts(rs.ctrlpts);
    }
  };
  BRp$c.getEdgeMidpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    return {
      x: rs.midX,
      y: rs.midY
    };
  };

  var BRp$b = {};
  BRp$b.manualEndptToPx = function (node, prop) {
    var r = this;
    var npos = node.position();
    var w = node.outerWidth();
    var h = node.outerHeight();
    if (prop.value.length === 2) {
      var p = [prop.pfValue[0], prop.pfValue[1]];
      if (prop.units[0] === '%') {
        p[0] = p[0] * w;
      }
      if (prop.units[1] === '%') {
        p[1] = p[1] * h;
      }
      p[0] += npos.x;
      p[1] += npos.y;
      return p;
    } else {
      var angle = prop.pfValue[0];
      angle = -Math.PI / 2 + angle; // start at 12 o'clock

      var l = 2 * Math.max(w, h);
      var _p = [npos.x + Math.cos(angle) * l, npos.y + Math.sin(angle) * l];
      return r.nodeShapes[this.getNodeShape(node)].intersectLine(npos.x, npos.y, w, h, _p[0], _p[1], 0);
    }
  };
  BRp$b.findEndpoints = function (edge) {
    var r = this;
    var intersect;
    var source = edge.source()[0];
    var target = edge.target()[0];
    var srcPos = source.position();
    var tgtPos = target.position();
    var tgtArShape = edge.pstyle('target-arrow-shape').value;
    var srcArShape = edge.pstyle('source-arrow-shape').value;
    var tgtDist = edge.pstyle('target-distance-from-node').pfValue;
    var srcDist = edge.pstyle('source-distance-from-node').pfValue;
    var curveStyle = edge.pstyle('curve-style').value;
    var rs = edge._private.rscratch;
    var et = rs.edgeType;
    var taxi = curveStyle === 'taxi';
    var self = et === 'self' || et === 'compound';
    var bezier = et === 'bezier' || et === 'multibezier' || self;
    var multi = et !== 'bezier';
    var lines = et === 'straight' || et === 'segments';
    var segments = et === 'segments';
    var hasEndpts = bezier || multi || lines;
    var overrideEndpts = self || taxi;
    var srcManEndpt = edge.pstyle('source-endpoint');
    var srcManEndptVal = overrideEndpts ? 'outside-to-node' : srcManEndpt.value;
    var tgtManEndpt = edge.pstyle('target-endpoint');
    var tgtManEndptVal = overrideEndpts ? 'outside-to-node' : tgtManEndpt.value;
    rs.srcManEndpt = srcManEndpt;
    rs.tgtManEndpt = tgtManEndpt;
    var p1; // last known point of edge on target side
    var p2; // last known point of edge on source side

    var p1_i; // point to intersect with target shape
    var p2_i; // point to intersect with source shape

    if (bezier) {
      var cpStart = [rs.ctrlpts[0], rs.ctrlpts[1]];
      var cpEnd = multi ? [rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1]] : cpStart;
      p1 = cpEnd;
      p2 = cpStart;
    } else if (lines) {
      var srcArrowFromPt = !segments ? [tgtPos.x, tgtPos.y] : rs.segpts.slice(0, 2);
      var tgtArrowFromPt = !segments ? [srcPos.x, srcPos.y] : rs.segpts.slice(rs.segpts.length - 2);
      p1 = tgtArrowFromPt;
      p2 = srcArrowFromPt;
    }
    if (tgtManEndptVal === 'inside-to-node') {
      intersect = [tgtPos.x, tgtPos.y];
    } else if (tgtManEndpt.units) {
      intersect = this.manualEndptToPx(target, tgtManEndpt);
    } else if (tgtManEndptVal === 'outside-to-line') {
      intersect = rs.tgtIntn; // use cached value from ctrlpt calc
    } else {
      if (tgtManEndptVal === 'outside-to-node' || tgtManEndptVal === 'outside-to-node-or-label') {
        p1_i = p1;
      } else if (tgtManEndptVal === 'outside-to-line' || tgtManEndptVal === 'outside-to-line-or-label') {
        p1_i = [srcPos.x, srcPos.y];
      }
      intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(tgtPos.x, tgtPos.y, target.outerWidth(), target.outerHeight(), p1_i[0], p1_i[1], 0);
      if (tgtManEndptVal === 'outside-to-node-or-label' || tgtManEndptVal === 'outside-to-line-or-label') {
        var trs = target._private.rscratch;
        var lw = trs.labelWidth;
        var lh = trs.labelHeight;
        var lx = trs.labelX;
        var ly = trs.labelY;
        var lw2 = lw / 2;
        var lh2 = lh / 2;
        var va = target.pstyle('text-valign').value;
        if (va === 'top') {
          ly -= lh2;
        } else if (va === 'bottom') {
          ly += lh2;
        }
        var ha = target.pstyle('text-halign').value;
        if (ha === 'left') {
          lx -= lw2;
        } else if (ha === 'right') {
          lx += lw2;
        }
        var labelIntersect = polygonIntersectLine(p1_i[0], p1_i[1], [lx - lw2, ly - lh2, lx + lw2, ly - lh2, lx + lw2, ly + lh2, lx - lw2, ly + lh2], tgtPos.x, tgtPos.y);
        if (labelIntersect.length > 0) {
          var refPt = srcPos;
          var intSqdist = sqdist(refPt, array2point(intersect));
          var labIntSqdist = sqdist(refPt, array2point(labelIntersect));
          var minSqDist = intSqdist;
          if (labIntSqdist < intSqdist) {
            intersect = labelIntersect;
            minSqDist = labIntSqdist;
          }
          if (labelIntersect.length > 2) {
            var labInt2SqDist = sqdist(refPt, {
              x: labelIntersect[2],
              y: labelIntersect[3]
            });
            if (labInt2SqDist < minSqDist) {
              intersect = [labelIntersect[2], labelIntersect[3]];
            }
          }
        }
      }
    }
    var arrowEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].spacing(edge) + tgtDist);
    var edgeEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].gap(edge) + tgtDist);
    rs.endX = edgeEnd[0];
    rs.endY = edgeEnd[1];
    rs.arrowEndX = arrowEnd[0];
    rs.arrowEndY = arrowEnd[1];
    if (srcManEndptVal === 'inside-to-node') {
      intersect = [srcPos.x, srcPos.y];
    } else if (srcManEndpt.units) {
      intersect = this.manualEndptToPx(source, srcManEndpt);
    } else if (srcManEndptVal === 'outside-to-line') {
      intersect = rs.srcIntn; // use cached value from ctrlpt calc
    } else {
      if (srcManEndptVal === 'outside-to-node' || srcManEndptVal === 'outside-to-node-or-label') {
        p2_i = p2;
      } else if (srcManEndptVal === 'outside-to-line' || srcManEndptVal === 'outside-to-line-or-label') {
        p2_i = [tgtPos.x, tgtPos.y];
      }
      intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(srcPos.x, srcPos.y, source.outerWidth(), source.outerHeight(), p2_i[0], p2_i[1], 0);
      if (srcManEndptVal === 'outside-to-node-or-label' || srcManEndptVal === 'outside-to-line-or-label') {
        var srs = source._private.rscratch;
        var _lw = srs.labelWidth;
        var _lh = srs.labelHeight;
        var _lx = srs.labelX;
        var _ly = srs.labelY;
        var _lw2 = _lw / 2;
        var _lh2 = _lh / 2;
        var _va = source.pstyle('text-valign').value;
        if (_va === 'top') {
          _ly -= _lh2;
        } else if (_va === 'bottom') {
          _ly += _lh2;
        }
        var _ha = source.pstyle('text-halign').value;
        if (_ha === 'left') {
          _lx -= _lw2;
        } else if (_ha === 'right') {
          _lx += _lw2;
        }
        var _labelIntersect = polygonIntersectLine(p2_i[0], p2_i[1], [_lx - _lw2, _ly - _lh2, _lx + _lw2, _ly - _lh2, _lx + _lw2, _ly + _lh2, _lx - _lw2, _ly + _lh2], srcPos.x, srcPos.y);
        if (_labelIntersect.length > 0) {
          var _refPt = tgtPos;
          var _intSqdist = sqdist(_refPt, array2point(intersect));
          var _labIntSqdist = sqdist(_refPt, array2point(_labelIntersect));
          var _minSqDist = _intSqdist;
          if (_labIntSqdist < _intSqdist) {
            intersect = [_labelIntersect[0], _labelIntersect[1]];
            _minSqDist = _labIntSqdist;
          }
          if (_labelIntersect.length > 2) {
            var _labInt2SqDist = sqdist(_refPt, {
              x: _labelIntersect[2],
              y: _labelIntersect[3]
            });
            if (_labInt2SqDist < _minSqDist) {
              intersect = [_labelIntersect[2], _labelIntersect[3]];
            }
          }
        }
      }
    }
    var arrowStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].spacing(edge) + srcDist);
    var edgeStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].gap(edge) + srcDist);
    rs.startX = edgeStart[0];
    rs.startY = edgeStart[1];
    rs.arrowStartX = arrowStart[0];
    rs.arrowStartY = arrowStart[1];
    if (hasEndpts) {
      if (!number$1(rs.startX) || !number$1(rs.startY) || !number$1(rs.endX) || !number$1(rs.endY)) {
        rs.badLine = true;
      } else {
        rs.badLine = false;
      }
    }
  };
  BRp$b.getSourceEndpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    switch (rs.edgeType) {
      case 'haystack':
        return {
          x: rs.haystackPts[0],
          y: rs.haystackPts[1]
        };
      default:
        return {
          x: rs.arrowStartX,
          y: rs.arrowStartY
        };
    }
  };
  BRp$b.getTargetEndpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    switch (rs.edgeType) {
      case 'haystack':
        return {
          x: rs.haystackPts[2],
          y: rs.haystackPts[3]
        };
      default:
        return {
          x: rs.arrowEndX,
          y: rs.arrowEndY
        };
    }
  };

  var BRp$a = {};
  function pushBezierPts(r, edge, pts) {
    var qbezierAt$1 = function qbezierAt$1(p1, p2, p3, t) {
      return qbezierAt(p1, p2, p3, t);
    };
    var _p = edge._private;
    var bpts = _p.rstyle.bezierPts;
    for (var i = 0; i < r.bezierProjPcts.length; i++) {
      var p = r.bezierProjPcts[i];
      bpts.push({
        x: qbezierAt$1(pts[0], pts[2], pts[4], p),
        y: qbezierAt$1(pts[1], pts[3], pts[5], p)
      });
    }
  }
  BRp$a.storeEdgeProjections = function (edge) {
    var _p = edge._private;
    var rs = _p.rscratch;
    var et = rs.edgeType;

    // clear the cached points state
    _p.rstyle.bezierPts = null;
    _p.rstyle.linePts = null;
    _p.rstyle.haystackPts = null;
    if (et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound') {
      _p.rstyle.bezierPts = [];
      for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
        pushBezierPts(this, edge, rs.allpts.slice(i, i + 6));
      }
    } else if (et === 'segments') {
      var lpts = _p.rstyle.linePts = [];
      for (var i = 0; i + 1 < rs.allpts.length; i += 2) {
        lpts.push({
          x: rs.allpts[i],
          y: rs.allpts[i + 1]
        });
      }
    } else if (et === 'haystack') {
      var hpts = rs.haystackPts;
      _p.rstyle.haystackPts = [{
        x: hpts[0],
        y: hpts[1]
      }, {
        x: hpts[2],
        y: hpts[3]
      }];
    }
    _p.rstyle.arrowWidth = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;
  };
  BRp$a.recalculateEdgeProjections = function (edges) {
    this.findEdgeControlPoints(edges);
  };

  /* global document */

  var BRp$9 = {};
  BRp$9.recalculateNodeLabelProjection = function (node) {
    var content = node.pstyle('label').strValue;
    if (emptyString(content)) {
      return;
    }
    var textX, textY;
    var _p = node._private;
    var nodeWidth = node.width();
    var nodeHeight = node.height();
    var padding = node.padding();
    var nodePos = node.position();
    var textHalign = node.pstyle('text-halign').strValue;
    var textValign = node.pstyle('text-valign').strValue;
    var rs = _p.rscratch;
    var rstyle = _p.rstyle;
    switch (textHalign) {
      case 'left':
        textX = nodePos.x - nodeWidth / 2 - padding;
        break;
      case 'right':
        textX = nodePos.x + nodeWidth / 2 + padding;
        break;
      default:
        // e.g. center
        textX = nodePos.x;
    }
    switch (textValign) {
      case 'top':
        textY = nodePos.y - nodeHeight / 2 - padding;
        break;
      case 'bottom':
        textY = nodePos.y + nodeHeight / 2 + padding;
        break;
      default:
        // e.g. middle
        textY = nodePos.y;
    }
    rs.labelX = textX;
    rs.labelY = textY;
    rstyle.labelX = textX;
    rstyle.labelY = textY;
    this.calculateLabelAngles(node);
    this.applyLabelDimensions(node);
  };
  var lineAngleFromDelta = function lineAngleFromDelta(dx, dy) {
    var angle = Math.atan(dy / dx);
    if (dx === 0 && angle < 0) {
      angle = angle * -1;
    }
    return angle;
  };
  var lineAngle = function lineAngle(p0, p1) {
    var dx = p1.x - p0.x;
    var dy = p1.y - p0.y;
    return lineAngleFromDelta(dx, dy);
  };
  var bezierAngle = function bezierAngle(p0, p1, p2, t) {
    var t0 = bound(0, t - 0.001, 1);
    var t1 = bound(0, t + 0.001, 1);
    var lp0 = qbezierPtAt(p0, p1, p2, t0);
    var lp1 = qbezierPtAt(p0, p1, p2, t1);
    return lineAngle(lp0, lp1);
  };
  BRp$9.recalculateEdgeLabelProjections = function (edge) {
    var p;
    var _p = edge._private;
    var rs = _p.rscratch;
    var r = this;
    var content = {
      mid: edge.pstyle('label').strValue,
      source: edge.pstyle('source-label').strValue,
      target: edge.pstyle('target-label').strValue
    };
    if (content.mid || content.source || content.target) ; else {
      return; // no labels => no calcs
    }

    // add center point to style so bounding box calculations can use it
    //
    p = {
      x: rs.midX,
      y: rs.midY
    };
    var setRs = function setRs(propName, prefix, value) {
      setPrefixedProperty(_p.rscratch, propName, prefix, value);
      setPrefixedProperty(_p.rstyle, propName, prefix, value);
    };
    setRs('labelX', null, p.x);
    setRs('labelY', null, p.y);
    var midAngle = lineAngleFromDelta(rs.midDispX, rs.midDispY);
    setRs('labelAutoAngle', null, midAngle);
    var createControlPointInfo = function createControlPointInfo() {
      if (createControlPointInfo.cache) {
        return createControlPointInfo.cache;
      } // use cache so only 1x per edge

      var ctrlpts = [];

      // store each ctrlpt info init
      for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
        var p0 = {
          x: rs.allpts[i],
          y: rs.allpts[i + 1]
        };
        var p1 = {
          x: rs.allpts[i + 2],
          y: rs.allpts[i + 3]
        }; // ctrlpt
        var p2 = {
          x: rs.allpts[i + 4],
          y: rs.allpts[i + 5]
        };
        ctrlpts.push({
          p0: p0,
          p1: p1,
          p2: p2,
          startDist: 0,
          length: 0,
          segments: []
        });
      }
      var bpts = _p.rstyle.bezierPts;
      var nProjs = r.bezierProjPcts.length;
      function addSegment(cp, p0, p1, t0, t1) {
        var length = dist(p0, p1);
        var prevSegment = cp.segments[cp.segments.length - 1];
        var segment = {
          p0: p0,
          p1: p1,
          t0: t0,
          t1: t1,
          startDist: prevSegment ? prevSegment.startDist + prevSegment.length : 0,
          length: length
        };
        cp.segments.push(segment);
        cp.length += length;
      }

      // update each ctrlpt with segment info
      for (var _i = 0; _i < ctrlpts.length; _i++) {
        var cp = ctrlpts[_i];
        var prevCp = ctrlpts[_i - 1];
        if (prevCp) {
          cp.startDist = prevCp.startDist + prevCp.length;
        }
        addSegment(cp, cp.p0, bpts[_i * nProjs], 0, r.bezierProjPcts[0]); // first

        for (var j = 0; j < nProjs - 1; j++) {
          addSegment(cp, bpts[_i * nProjs + j], bpts[_i * nProjs + j + 1], r.bezierProjPcts[j], r.bezierProjPcts[j + 1]);
        }
        addSegment(cp, bpts[_i * nProjs + nProjs - 1], cp.p2, r.bezierProjPcts[nProjs - 1], 1); // last
      }

      return createControlPointInfo.cache = ctrlpts;
    };
    var calculateEndProjection = function calculateEndProjection(prefix) {
      var angle;
      var isSrc = prefix === 'source';
      if (!content[prefix]) {
        return;
      }
      var offset = edge.pstyle(prefix + '-text-offset').pfValue;
      switch (rs.edgeType) {
        case 'self':
        case 'compound':
        case 'bezier':
        case 'multibezier':
          {
            var cps = createControlPointInfo();
            var selected;
            var startDist = 0;
            var totalDist = 0;

            // find the segment we're on
            for (var i = 0; i < cps.length; i++) {
              var _cp = cps[isSrc ? i : cps.length - 1 - i];
              for (var j = 0; j < _cp.segments.length; j++) {
                var _seg = _cp.segments[isSrc ? j : _cp.segments.length - 1 - j];
                var lastSeg = i === cps.length - 1 && j === _cp.segments.length - 1;
                startDist = totalDist;
                totalDist += _seg.length;
                if (totalDist >= offset || lastSeg) {
                  selected = {
                    cp: _cp,
                    segment: _seg
                  };
                  break;
                }
              }
              if (selected) {
                break;
              }
            }
            var cp = selected.cp;
            var seg = selected.segment;
            var tSegment = (offset - startDist) / seg.length;
            var segDt = seg.t1 - seg.t0;
            var t = isSrc ? seg.t0 + segDt * tSegment : seg.t1 - segDt * tSegment;
            t = bound(0, t, 1);
            p = qbezierPtAt(cp.p0, cp.p1, cp.p2, t);
            angle = bezierAngle(cp.p0, cp.p1, cp.p2, t);
            break;
          }
        case 'straight':
        case 'segments':
        case 'haystack':
          {
            var d = 0,
              di,
              d0;
            var p0, p1;
            var l = rs.allpts.length;
            for (var _i2 = 0; _i2 + 3 < l; _i2 += 2) {
              if (isSrc) {
                p0 = {
                  x: rs.allpts[_i2],
                  y: rs.allpts[_i2 + 1]
                };
                p1 = {
                  x: rs.allpts[_i2 + 2],
                  y: rs.allpts[_i2 + 3]
                };
              } else {
                p0 = {
                  x: rs.allpts[l - 2 - _i2],
                  y: rs.allpts[l - 1 - _i2]
                };
                p1 = {
                  x: rs.allpts[l - 4 - _i2],
                  y: rs.allpts[l - 3 - _i2]
                };
              }
              di = dist(p0, p1);
              d0 = d;
              d += di;
              if (d >= offset) {
                break;
              }
            }
            var pD = offset - d0;
            var _t = pD / di;
            _t = bound(0, _t, 1);
            p = lineAt(p0, p1, _t);
            angle = lineAngle(p0, p1);
            break;
          }
      }
      setRs('labelX', prefix, p.x);
      setRs('labelY', prefix, p.y);
      setRs('labelAutoAngle', prefix, angle);
    };
    calculateEndProjection('source');
    calculateEndProjection('target');
    this.applyLabelDimensions(edge);
  };
  BRp$9.applyLabelDimensions = function (ele) {
    this.applyPrefixedLabelDimensions(ele);
    if (ele.isEdge()) {
      this.applyPrefixedLabelDimensions(ele, 'source');
      this.applyPrefixedLabelDimensions(ele, 'target');
    }
  };
  BRp$9.applyPrefixedLabelDimensions = function (ele, prefix) {
    var _p = ele._private;
    var text = this.getLabelText(ele, prefix);
    var labelDims = this.calculateLabelDimensions(ele, text);
    var lineHeight = ele.pstyle('line-height').pfValue;
    var textWrap = ele.pstyle('text-wrap').strValue;
    var lines = getPrefixedProperty(_p.rscratch, 'labelWrapCachedLines', prefix) || [];
    var numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1);
    var normPerLineHeight = labelDims.height / numLines;
    var labelLineHeight = normPerLineHeight * lineHeight;
    var width = labelDims.width;
    var height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight;
    setPrefixedProperty(_p.rstyle, 'labelWidth', prefix, width);
    setPrefixedProperty(_p.rscratch, 'labelWidth', prefix, width);
    setPrefixedProperty(_p.rstyle, 'labelHeight', prefix, height);
    setPrefixedProperty(_p.rscratch, 'labelHeight', prefix, height);
    setPrefixedProperty(_p.rscratch, 'labelLineHeight', prefix, labelLineHeight);
  };
  BRp$9.getLabelText = function (ele, prefix) {
    var _p = ele._private;
    var pfd = prefix ? prefix + '-' : '';
    var text = ele.pstyle(pfd + 'label').strValue;
    var textTransform = ele.pstyle('text-transform').value;
    var rscratch = function rscratch(propName, value) {
      if (value) {
        setPrefixedProperty(_p.rscratch, propName, prefix, value);
        return value;
      } else {
        return getPrefixedProperty(_p.rscratch, propName, prefix);
      }
    };

    // for empty text, skip all processing
    if (!text) {
      return '';
    }
    if (textTransform == 'none') ; else if (textTransform == 'uppercase') {
      text = text.toUpperCase();
    } else if (textTransform == 'lowercase') {
      text = text.toLowerCase();
    }
    var wrapStyle = ele.pstyle('text-wrap').value;
    if (wrapStyle === 'wrap') {
      var labelKey = rscratch('labelKey');

      // save recalc if the label is the same as before
      if (labelKey != null && rscratch('labelWrapKey') === labelKey) {
        return rscratch('labelWrapCachedText');
      }
      var zwsp = "\u200B";
      var lines = text.split('\n');
      var maxW = ele.pstyle('text-max-width').pfValue;
      var overflow = ele.pstyle('text-overflow-wrap').value;
      var overflowAny = overflow === 'anywhere';
      var wrappedLines = [];
      var wordsRegex = /[\s\u200b]+/;
      var wordSeparator = overflowAny ? '' : ' ';
      for (var l = 0; l < lines.length; l++) {
        var line = lines[l];
        var lineDims = this.calculateLabelDimensions(ele, line);
        var lineW = lineDims.width;
        if (overflowAny) {
          var processedLine = line.split('').join(zwsp);
          line = processedLine;
        }
        if (lineW > maxW) {
          // line is too long
          var words = line.split(wordsRegex);
          var subline = '';
          for (var w = 0; w < words.length; w++) {
            var word = words[w];
            var testLine = subline.length === 0 ? word : subline + wordSeparator + word;
            var testDims = this.calculateLabelDimensions(ele, testLine);
            var testW = testDims.width;
            if (testW <= maxW) {
              // word fits on current line
              subline += word + wordSeparator;
            } else {
              // word starts new line
              if (subline) {
                wrappedLines.push(subline);
              }
              subline = word + wordSeparator;
            }
          }

          // if there's remaining text, put it in a wrapped line
          if (!subline.match(/^[\s\u200b]+$/)) {
            wrappedLines.push(subline);
          }
        } else {
          // line is already short enough
          wrappedLines.push(line);
        }
      } // for

      rscratch('labelWrapCachedLines', wrappedLines);
      text = rscratch('labelWrapCachedText', wrappedLines.join('\n'));
      rscratch('labelWrapKey', labelKey);
    } else if (wrapStyle === 'ellipsis') {
      var _maxW = ele.pstyle('text-max-width').pfValue;
      var ellipsized = '';
      var ellipsis = "\u2026";
      var incLastCh = false;
      if (this.calculateLabelDimensions(ele, text).width < _maxW) {
        // the label already fits
        return text;
      }
      for (var i = 0; i < text.length; i++) {
        var widthWithNextCh = this.calculateLabelDimensions(ele, ellipsized + text[i] + ellipsis).width;
        if (widthWithNextCh > _maxW) {
          break;
        }
        ellipsized += text[i];
        if (i === text.length - 1) {
          incLastCh = true;
        }
      }
      if (!incLastCh) {
        ellipsized += ellipsis;
      }
      return ellipsized;
    } // if ellipsize

    return text;
  };
  BRp$9.getLabelJustification = function (ele) {
    var justification = ele.pstyle('text-justification').strValue;
    var textHalign = ele.pstyle('text-halign').strValue;
    if (justification === 'auto') {
      if (ele.isNode()) {
        switch (textHalign) {
          case 'left':
            return 'right';
          case 'right':
            return 'left';
          default:
            return 'center';
        }
      } else {
        return 'center';
      }
    } else {
      return justification;
    }
  };
  BRp$9.calculateLabelDimensions = function (ele, text) {
    var r = this;
    var cacheKey = hashString(text, ele._private.labelDimsKey);
    var cache = r.labelDimCache || (r.labelDimCache = []);
    var existingVal = cache[cacheKey];
    if (existingVal != null) {
      return existingVal;
    }
    var padding = 0; // add padding around text dims, as the measurement isn't that accurate
    var fStyle = ele.pstyle('font-style').strValue;
    var size = ele.pstyle('font-size').pfValue;
    var family = ele.pstyle('font-family').strValue;
    var weight = ele.pstyle('font-weight').strValue;
    var canvas = this.labelCalcCanvas;
    var c2d = this.labelCalcCanvasContext;
    if (!canvas) {
      canvas = this.labelCalcCanvas = document.createElement('canvas');
      c2d = this.labelCalcCanvasContext = canvas.getContext('2d');
      var ds = canvas.style;
      ds.position = 'absolute';
      ds.left = '-9999px';
      ds.top = '-9999px';
      ds.zIndex = '-1';
      ds.visibility = 'hidden';
      ds.pointerEvents = 'none';
    }
    c2d.font = "".concat(fStyle, " ").concat(weight, " ").concat(size, "px ").concat(family);
    var width = 0;
    var height = 0;
    var lines = text.split('\n');
    for (var i = 0; i < lines.length; i++) {
      var line = lines[i];
      var metrics = c2d.measureText(line);
      var w = Math.ceil(metrics.width);
      var h = size;
      width = Math.max(w, width);
      height += h;
    }
    width += padding;
    height += padding;
    return cache[cacheKey] = {
      width: width,
      height: height
    };
  };
  BRp$9.calculateLabelAngle = function (ele, prefix) {
    var _p = ele._private;
    var rs = _p.rscratch;
    var isEdge = ele.isEdge();
    var prefixDash = prefix ? prefix + '-' : '';
    var rot = ele.pstyle(prefixDash + 'text-rotation');
    var rotStr = rot.strValue;
    if (rotStr === 'none') {
      return 0;
    } else if (isEdge && rotStr === 'autorotate') {
      return rs.labelAutoAngle;
    } else if (rotStr === 'autorotate') {
      return 0;
    } else {
      return rot.pfValue;
    }
  };
  BRp$9.calculateLabelAngles = function (ele) {
    var r = this;
    var isEdge = ele.isEdge();
    var _p = ele._private;
    var rs = _p.rscratch;
    rs.labelAngle = r.calculateLabelAngle(ele);
    if (isEdge) {
      rs.sourceLabelAngle = r.calculateLabelAngle(ele, 'source');
      rs.targetLabelAngle = r.calculateLabelAngle(ele, 'target');
    }
  };

  var BRp$8 = {};
  var TOO_SMALL_CUT_RECT = 28;
  var warnedCutRect = false;
  BRp$8.getNodeShape = function (node) {
    var r = this;
    var shape = node.pstyle('shape').value;
    if (shape === 'cutrectangle' && (node.width() < TOO_SMALL_CUT_RECT || node.height() < TOO_SMALL_CUT_RECT)) {
      if (!warnedCutRect) {
        warn('The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead');
        warnedCutRect = true;
      }
      return 'rectangle';
    }
    if (node.isParent()) {
      if (shape === 'rectangle' || shape === 'roundrectangle' || shape === 'round-rectangle' || shape === 'cutrectangle' || shape === 'cut-rectangle' || shape === 'barrel') {
        return shape;
      } else {
        return 'rectangle';
      }
    }
    if (shape === 'polygon') {
      var points = node.pstyle('shape-polygon-points').value;
      return r.nodeShapes.makePolygon(points).name;
    }
    return shape;
  };

  var BRp$7 = {};
  BRp$7.registerCalculationListeners = function () {
    var cy = this.cy;
    var elesToUpdate = cy.collection();
    var r = this;
    var enqueue = function enqueue(eles) {
      var dirtyStyleCaches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      elesToUpdate.merge(eles);
      if (dirtyStyleCaches) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var _p = ele._private;
          var rstyle = _p.rstyle;
          rstyle.clean = false;
          rstyle.cleanConnected = false;
        }
      }
    };
    r.binder(cy).on('bounds.* dirty.*', function onDirtyBounds(e) {
      var ele = e.target;
      enqueue(ele);
    }).on('style.* background.*', function onDirtyStyle(e) {
      var ele = e.target;
      enqueue(ele, false);
    });
    var updateEleCalcs = function updateEleCalcs(willDraw) {
      if (willDraw) {
        var fns = r.onUpdateEleCalcsFns;

        // because we need to have up-to-date style (e.g. stylesheet mappers)
        // before calculating rendered style (and pstyle might not be called yet)
        elesToUpdate.cleanStyle();
        for (var i = 0; i < elesToUpdate.length; i++) {
          var ele = elesToUpdate[i];
          var rstyle = ele._private.rstyle;
          if (ele.isNode() && !rstyle.cleanConnected) {
            enqueue(ele.connectedEdges());
            rstyle.cleanConnected = true;
          }
        }
        if (fns) {
          for (var _i = 0; _i < fns.length; _i++) {
            var fn = fns[_i];
            fn(willDraw, elesToUpdate);
          }
        }
        r.recalculateRenderedStyle(elesToUpdate);
        elesToUpdate = cy.collection();
      }
    };
    r.flushRenderedStyleQueue = function () {
      updateEleCalcs(true);
    };
    r.beforeRender(updateEleCalcs, r.beforeRenderPriorities.eleCalcs);
  };
  BRp$7.onUpdateEleCalcs = function (fn) {
    var fns = this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || [];
    fns.push(fn);
  };
  BRp$7.recalculateRenderedStyle = function (eles, useCache) {
    var isCleanConnected = function isCleanConnected(ele) {
      return ele._private.rstyle.cleanConnected;
    };
    var edges = [];
    var nodes = [];

    // the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox()
    if (this.destroyed) {
      return;
    }

    // use cache by default for perf
    if (useCache === undefined) {
      useCache = true;
    }
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var _p = ele._private;
      var rstyle = _p.rstyle;

      // an edge may be implicitly dirty b/c of one of its connected nodes
      // (and a request for recalc may come in between frames)
      if (ele.isEdge() && (!isCleanConnected(ele.source()) || !isCleanConnected(ele.target()))) {
        rstyle.clean = false;
      }

      // only update if dirty and in graph
      if (useCache && rstyle.clean || ele.removed()) {
        continue;
      }

      // only update if not display: none
      if (ele.pstyle('display').value === 'none') {
        continue;
      }
      if (_p.group === 'nodes') {
        nodes.push(ele);
      } else {
        // edges
        edges.push(ele);
      }
      rstyle.clean = true;
    }

    // update node data from projections
    for (var _i2 = 0; _i2 < nodes.length; _i2++) {
      var _ele = nodes[_i2];
      var _p2 = _ele._private;
      var _rstyle = _p2.rstyle;
      var pos = _ele.position();
      this.recalculateNodeLabelProjection(_ele);
      _rstyle.nodeX = pos.x;
      _rstyle.nodeY = pos.y;
      _rstyle.nodeW = _ele.pstyle('width').pfValue;
      _rstyle.nodeH = _ele.pstyle('height').pfValue;
    }
    this.recalculateEdgeProjections(edges);

    // update edge data from projections
    for (var _i3 = 0; _i3 < edges.length; _i3++) {
      var _ele2 = edges[_i3];
      var _p3 = _ele2._private;
      var _rstyle2 = _p3.rstyle;
      var rs = _p3.rscratch;

      // update rstyle positions
      _rstyle2.srcX = rs.arrowStartX;
      _rstyle2.srcY = rs.arrowStartY;
      _rstyle2.tgtX = rs.arrowEndX;
      _rstyle2.tgtY = rs.arrowEndY;
      _rstyle2.midX = rs.midX;
      _rstyle2.midY = rs.midY;
      _rstyle2.labelAngle = rs.labelAngle;
      _rstyle2.sourceLabelAngle = rs.sourceLabelAngle;
      _rstyle2.targetLabelAngle = rs.targetLabelAngle;
    }
  };

  var BRp$6 = {};
  BRp$6.updateCachedGrabbedEles = function () {
    var eles = this.cachedZSortedEles;
    if (!eles) {
      // just let this be recalculated on the next z sort tick
      return;
    }
    eles.drag = [];
    eles.nondrag = [];
    var grabTargets = [];
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var rs = ele._private.rscratch;
      if (ele.grabbed() && !ele.isParent()) {
        grabTargets.push(ele);
      } else if (rs.inDragLayer) {
        eles.drag.push(ele);
      } else {
        eles.nondrag.push(ele);
      }
    }

    // put the grab target nodes last so it's on top of its neighbourhood
    for (var i = 0; i < grabTargets.length; i++) {
      var ele = grabTargets[i];
      eles.drag.push(ele);
    }
  };
  BRp$6.invalidateCachedZSortedEles = function () {
    this.cachedZSortedEles = null;
  };
  BRp$6.getCachedZSortedEles = function (forceRecalc) {
    if (forceRecalc || !this.cachedZSortedEles) {
      var eles = this.cy.mutableElements().toArray();
      eles.sort(zIndexSort);
      eles.interactive = eles.filter(function (ele) {
        return ele.interactive();
      });
      this.cachedZSortedEles = eles;
      this.updateCachedGrabbedEles();
    } else {
      eles = this.cachedZSortedEles;
    }
    return eles;
  };

  var BRp$5 = {};
  [BRp$e, BRp$d, BRp$c, BRp$b, BRp$a, BRp$9, BRp$8, BRp$7, BRp$6].forEach(function (props) {
    extend(BRp$5, props);
  });

  var BRp$4 = {};
  BRp$4.getCachedImage = function (url, crossOrigin, onLoad) {
    var r = this;
    var imageCache = r.imageCache = r.imageCache || {};
    var cache = imageCache[url];
    if (cache) {
      if (!cache.image.complete) {
        cache.image.addEventListener('load', onLoad);
      }
      return cache.image;
    } else {
      cache = imageCache[url] = imageCache[url] || {};
      var image = cache.image = new Image(); // eslint-disable-line no-undef

      image.addEventListener('load', onLoad);
      image.addEventListener('error', function () {
        image.error = true;
      });

      // #1582 safari doesn't load data uris with crossOrigin properly
      // https://bugs.webkit.org/show_bug.cgi?id=123978
      var dataUriPrefix = 'data:';
      var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix;
      if (!isDataUri) {
        // if crossorigin is 'null'(stringified), then manually set it to null 
        crossOrigin = crossOrigin === 'null' ? null : crossOrigin;
        image.crossOrigin = crossOrigin; // prevent tainted canvas
      }

      image.src = url;
      return image;
    }
  };

  var BRp$3 = {};

  /* global document, window, ResizeObserver, MutationObserver */

  BRp$3.registerBinding = function (target, event, handler, useCapture) {
    // eslint-disable-line no-unused-vars
    var args = Array.prototype.slice.apply(arguments, [1]); // copy
    var b = this.binder(target);
    return b.on.apply(b, args);
  };
  BRp$3.binder = function (tgt) {
    var r = this;
    var containerWindow = r.cy.window();
    var tgtIsDom = tgt === containerWindow || tgt === containerWindow.document || tgt === containerWindow.document.body || domElement(tgt);
    if (r.supportsPassiveEvents == null) {
      // from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
      var supportsPassive = false;
      try {
        var opts = Object.defineProperty({}, 'passive', {
          get: function get() {
            supportsPassive = true;
            return true;
          }
        });
        containerWindow.addEventListener('test', null, opts);
      } catch (err) {
        // not supported
      }
      r.supportsPassiveEvents = supportsPassive;
    }
    var on = function on(event, handler, useCapture) {
      var args = Array.prototype.slice.call(arguments);
      if (tgtIsDom && r.supportsPassiveEvents) {
        // replace useCapture w/ opts obj
        args[2] = {
          capture: useCapture != null ? useCapture : false,
          passive: false,
          once: false
        };
      }
      r.bindings.push({
        target: tgt,
        args: args
      });
      (tgt.addEventListener || tgt.on).apply(tgt, args);
      return this;
    };
    return {
      on: on,
      addEventListener: on,
      addListener: on,
      bind: on
    };
  };
  BRp$3.nodeIsDraggable = function (node) {
    return node && node.isNode() && !node.locked() && node.grabbable();
  };
  BRp$3.nodeIsGrabbable = function (node) {
    return this.nodeIsDraggable(node) && node.interactive();
  };
  BRp$3.load = function () {
    var r = this;
    var containerWindow = r.cy.window();
    var isSelected = function isSelected(ele) {
      return ele.selected();
    };
    var triggerEvents = function triggerEvents(target, names, e, position) {
      if (target == null) {
        target = r.cy;
      }
      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        target.emit({
          originalEvent: e,
          type: name,
          position: position
        });
      }
    };
    var isMultSelKeyDown = function isMultSelKeyDown(e) {
      return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey
    };

    var allowPanningPassthrough = function allowPanningPassthrough(down, downs) {
      var allowPassthrough = true;
      if (r.cy.hasCompoundNodes() && down && down.pannable()) {
        // a grabbable compound node below the ele => no passthrough panning
        for (var i = 0; downs && i < downs.length; i++) {
          var down = downs[i];

          //if any parent node in event hierarchy isn't pannable, reject passthrough
          if (down.isNode() && down.isParent() && !down.pannable()) {
            allowPassthrough = false;
            break;
          }
        }
      } else {
        allowPassthrough = true;
      }
      return allowPassthrough;
    };
    var setGrabbed = function setGrabbed(ele) {
      ele[0]._private.grabbed = true;
    };
    var setFreed = function setFreed(ele) {
      ele[0]._private.grabbed = false;
    };
    var setInDragLayer = function setInDragLayer(ele) {
      ele[0]._private.rscratch.inDragLayer = true;
    };
    var setOutDragLayer = function setOutDragLayer(ele) {
      ele[0]._private.rscratch.inDragLayer = false;
    };
    var setGrabTarget = function setGrabTarget(ele) {
      ele[0]._private.rscratch.isGrabTarget = true;
    };
    var removeGrabTarget = function removeGrabTarget(ele) {
      ele[0]._private.rscratch.isGrabTarget = false;
    };
    var addToDragList = function addToDragList(ele, opts) {
      var list = opts.addToList;
      var listHasEle = list.has(ele);
      if (!listHasEle && ele.grabbable() && !ele.locked()) {
        list.merge(ele);
        setGrabbed(ele);
      }
    };

    // helper function to determine which child nodes and inner edges
    // of a compound node to be dragged as well as the grabbed and selected nodes
    var addDescendantsToDrag = function addDescendantsToDrag(node, opts) {
      if (!node.cy().hasCompoundNodes()) {
        return;
      }
      if (opts.inDragLayer == null && opts.addToList == null) {
        return;
      } // nothing to do

      var innerNodes = node.descendants();
      if (opts.inDragLayer) {
        innerNodes.forEach(setInDragLayer);
        innerNodes.connectedEdges().forEach(setInDragLayer);
      }
      if (opts.addToList) {
        addToDragList(innerNodes, opts);
      }
    };

    // adds the given nodes and its neighbourhood to the drag layer
    var addNodesToDrag = function addNodesToDrag(nodes, opts) {
      opts = opts || {};
      var hasCompoundNodes = nodes.cy().hasCompoundNodes();
      if (opts.inDragLayer) {
        nodes.forEach(setInDragLayer);
        nodes.neighborhood().stdFilter(function (ele) {
          return !hasCompoundNodes || ele.isEdge();
        }).forEach(setInDragLayer);
      }
      if (opts.addToList) {
        nodes.forEach(function (ele) {
          addToDragList(ele, opts);
        });
      }
      addDescendantsToDrag(nodes, opts); // always add to drag

      // also add nodes and edges related to the topmost ancestor
      updateAncestorsInDragLayer(nodes, {
        inDragLayer: opts.inDragLayer
      });
      r.updateCachedGrabbedEles();
    };
    var addNodeToDrag = addNodesToDrag;
    var freeDraggedElements = function freeDraggedElements(grabbedEles) {
      if (!grabbedEles) {
        return;
      }

      // just go over all elements rather than doing a bunch of (possibly expensive) traversals
      r.getCachedZSortedEles().forEach(function (ele) {
        setFreed(ele);
        setOutDragLayer(ele);
        removeGrabTarget(ele);
      });
      r.updateCachedGrabbedEles();
    };

    // helper function to determine which ancestor nodes and edges should go
    // to the drag layer (or should be removed from drag layer).
    var updateAncestorsInDragLayer = function updateAncestorsInDragLayer(node, opts) {
      if (opts.inDragLayer == null && opts.addToList == null) {
        return;
      } // nothing to do

      if (!node.cy().hasCompoundNodes()) {
        return;
      }

      // find top-level parent
      var parent = node.ancestors().orphans();

      // no parent node: no nodes to add to the drag layer
      if (parent.same(node)) {
        return;
      }
      var nodes = parent.descendants().spawnSelf().merge(parent).unmerge(node).unmerge(node.descendants());
      var edges = nodes.connectedEdges();
      if (opts.inDragLayer) {
        edges.forEach(setInDragLayer);
        nodes.forEach(setInDragLayer);
      }
      if (opts.addToList) {
        nodes.forEach(function (ele) {
          addToDragList(ele, opts);
        });
      }
    };
    var blurActiveDomElement = function blurActiveDomElement() {
      if (document.activeElement != null && document.activeElement.blur != null) {
        document.activeElement.blur();
      }
    };
    var haveMutationsApi = typeof MutationObserver !== 'undefined';
    var haveResizeObserverApi = typeof ResizeObserver !== 'undefined';

    // watch for when the cy container is removed from the dom
    if (haveMutationsApi) {
      r.removeObserver = new MutationObserver(function (mutns) {
        // eslint-disable-line no-undef
        for (var i = 0; i < mutns.length; i++) {
          var mutn = mutns[i];
          var rNodes = mutn.removedNodes;
          if (rNodes) {
            for (var j = 0; j < rNodes.length; j++) {
              var rNode = rNodes[j];
              if (rNode === r.container) {
                r.destroy();
                break;
              }
            }
          }
        }
      });
      if (r.container.parentNode) {
        r.removeObserver.observe(r.container.parentNode, {
          childList: true
        });
      }
    } else {
      r.registerBinding(r.container, 'DOMNodeRemoved', function (e) {
        // eslint-disable-line no-unused-vars
        r.destroy();
      });
    }
    var onResize = debounce_1(function () {
      r.cy.resize();
    }, 100);
    if (haveMutationsApi) {
      r.styleObserver = new MutationObserver(onResize); // eslint-disable-line no-undef

      r.styleObserver.observe(r.container, {
        attributes: true
      });
    }

    // auto resize
    r.registerBinding(containerWindow, 'resize', onResize); // eslint-disable-line no-undef

    if (haveResizeObserverApi) {
      r.resizeObserver = new ResizeObserver(onResize); // eslint-disable-line no-undef

      r.resizeObserver.observe(r.container);
    }
    var forEachUp = function forEachUp(domEle, fn) {
      while (domEle != null) {
        fn(domEle);
        domEle = domEle.parentNode;
      }
    };
    var invalidateCoords = function invalidateCoords() {
      r.invalidateContainerClientCoordsCache();
    };
    forEachUp(r.container, function (domEle) {
      r.registerBinding(domEle, 'transitionend', invalidateCoords);
      r.registerBinding(domEle, 'animationend', invalidateCoords);
      r.registerBinding(domEle, 'scroll', invalidateCoords);
    });

    // stop right click menu from appearing on cy
    r.registerBinding(r.container, 'contextmenu', function (e) {
      e.preventDefault();
    });
    var inBoxSelection = function inBoxSelection() {
      return r.selection[4] !== 0;
    };
    var eventInContainer = function eventInContainer(e) {
      // save cycles if mouse events aren't to be captured
      var containerPageCoords = r.findContainerClientCoords();
      var x = containerPageCoords[0];
      var y = containerPageCoords[1];
      var width = containerPageCoords[2];
      var height = containerPageCoords[3];
      var positions = e.touches ? e.touches : [e];
      var atLeastOnePosInside = false;
      for (var i = 0; i < positions.length; i++) {
        var p = positions[i];
        if (x <= p.clientX && p.clientX <= x + width && y <= p.clientY && p.clientY <= y + height) {
          atLeastOnePosInside = true;
          break;
        }
      }
      if (!atLeastOnePosInside) {
        return false;
      }
      var container = r.container;
      var target = e.target;
      var tParent = target.parentNode;
      var containerIsTarget = false;
      while (tParent) {
        if (tParent === container) {
          containerIsTarget = true;
          break;
        }
        tParent = tParent.parentNode;
      }
      if (!containerIsTarget) {
        return false;
      } // if target is outisde cy container, then this event is not for us

      return true;
    };

    // Primary key
    r.registerBinding(r.container, 'mousedown', function mousedownHandler(e) {
      if (!eventInContainer(e)) {
        return;
      }
      e.preventDefault();
      blurActiveDomElement();
      r.hoverData.capture = true;
      r.hoverData.which = e.which;
      var cy = r.cy;
      var gpos = [e.clientX, e.clientY];
      var pos = r.projectIntoViewport(gpos[0], gpos[1]);
      var select = r.selection;
      var nears = r.findNearestElements(pos[0], pos[1], true, false);
      var near = nears[0];
      var draggedElements = r.dragData.possibleDragElements;
      r.hoverData.mdownPos = pos;
      r.hoverData.mdownGPos = gpos;
      var checkForTaphold = function checkForTaphold() {
        r.hoverData.tapholdCancelled = false;
        clearTimeout(r.hoverData.tapholdTimeout);
        r.hoverData.tapholdTimeout = setTimeout(function () {
          if (r.hoverData.tapholdCancelled) {
            return;
          } else {
            var ele = r.hoverData.down;
            if (ele) {
              ele.emit({
                originalEvent: e,
                type: 'taphold',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            } else {
              cy.emit({
                originalEvent: e,
                type: 'taphold',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
          }
        }, r.tapholdDuration);
      };

      // Right click button
      if (e.which == 3) {
        r.hoverData.cxtStarted = true;
        var cxtEvt = {
          originalEvent: e,
          type: 'cxttapstart',
          position: {
            x: pos[0],
            y: pos[1]
          }
        };
        if (near) {
          near.activate();
          near.emit(cxtEvt);
          r.hoverData.down = near;
        } else {
          cy.emit(cxtEvt);
        }
        r.hoverData.downTime = new Date().getTime();
        r.hoverData.cxtDragged = false;

        // Primary button
      } else if (e.which == 1) {
        if (near) {
          near.activate();
        }

        // Element dragging
        {
          // If something is under the cursor and it is draggable, prepare to grab it
          if (near != null) {
            if (r.nodeIsGrabbable(near)) {
              var makeEvent = function makeEvent(type) {
                return {
                  originalEvent: e,
                  type: type,
                  position: {
                    x: pos[0],
                    y: pos[1]
                  }
                };
              };
              var triggerGrab = function triggerGrab(ele) {
                ele.emit(makeEvent('grab'));
              };
              setGrabTarget(near);
              if (!near.selected()) {
                draggedElements = r.dragData.possibleDragElements = cy.collection();
                addNodeToDrag(near, {
                  addToList: draggedElements
                });
                near.emit(makeEvent('grabon')).emit(makeEvent('grab'));
              } else {
                draggedElements = r.dragData.possibleDragElements = cy.collection();
                var selectedNodes = cy.$(function (ele) {
                  return ele.isNode() && ele.selected() && r.nodeIsGrabbable(ele);
                });
                addNodesToDrag(selectedNodes, {
                  addToList: draggedElements
                });
                near.emit(makeEvent('grabon'));
                selectedNodes.forEach(triggerGrab);
              }
              r.redrawHint('eles', true);
              r.redrawHint('drag', true);
            }
          }
          r.hoverData.down = near;
          r.hoverData.downs = nears;
          r.hoverData.downTime = new Date().getTime();
        }
        triggerEvents(near, ['mousedown', 'tapstart', 'vmousedown'], e, {
          x: pos[0],
          y: pos[1]
        });
        if (near == null) {
          select[4] = 1;
          r.data.bgActivePosistion = {
            x: pos[0],
            y: pos[1]
          };
          r.redrawHint('select', true);
          r.redraw();
        } else if (near.pannable()) {
          select[4] = 1; // for future pan
        }

        checkForTaphold();
      }

      // Initialize selection box coordinates
      select[0] = select[2] = pos[0];
      select[1] = select[3] = pos[1];
    }, false);
    r.registerBinding(containerWindow, 'mousemove', function mousemoveHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.hoverData.capture;
      if (!capture && !eventInContainer(e)) {
        return;
      }
      var preventDefault = false;
      var cy = r.cy;
      var zoom = cy.zoom();
      var gpos = [e.clientX, e.clientY];
      var pos = r.projectIntoViewport(gpos[0], gpos[1]);
      var mdownPos = r.hoverData.mdownPos;
      var mdownGPos = r.hoverData.mdownGPos;
      var select = r.selection;
      var near = null;
      if (!r.hoverData.draggingEles && !r.hoverData.dragging && !r.hoverData.selecting) {
        near = r.findNearestElement(pos[0], pos[1], true, false);
      }
      var last = r.hoverData.last;
      var down = r.hoverData.down;
      var disp = [pos[0] - select[2], pos[1] - select[3]];
      var draggedElements = r.dragData.possibleDragElements;
      var isOverThresholdDrag;
      if (mdownGPos) {
        var dx = gpos[0] - mdownGPos[0];
        var dx2 = dx * dx;
        var dy = gpos[1] - mdownGPos[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        r.hoverData.isOverThresholdDrag = isOverThresholdDrag = dist2 >= r.desktopTapThreshold2;
      }
      var multSelKeyDown = isMultSelKeyDown(e);
      if (isOverThresholdDrag) {
        r.hoverData.tapholdCancelled = true;
      }
      var updateDragDelta = function updateDragDelta() {
        var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || [];
        if (dragDelta.length === 0) {
          dragDelta.push(disp[0]);
          dragDelta.push(disp[1]);
        } else {
          dragDelta[0] += disp[0];
          dragDelta[1] += disp[1];
        }
      };
      preventDefault = true;
      triggerEvents(near, ['mousemove', 'vmousemove', 'tapdrag'], e, {
        x: pos[0],
        y: pos[1]
      });
      var goIntoBoxMode = function goIntoBoxMode() {
        r.data.bgActivePosistion = undefined;
        if (!r.hoverData.selecting) {
          cy.emit({
            originalEvent: e,
            type: 'boxstart',
            position: {
              x: pos[0],
              y: pos[1]
            }
          });
        }
        select[4] = 1;
        r.hoverData.selecting = true;
        r.redrawHint('select', true);
        r.redraw();
      };

      // trigger context drag if rmouse down
      if (r.hoverData.which === 3) {
        // but only if over threshold
        if (isOverThresholdDrag) {
          var cxtEvt = {
            originalEvent: e,
            type: 'cxtdrag',
            position: {
              x: pos[0],
              y: pos[1]
            }
          };
          if (down) {
            down.emit(cxtEvt);
          } else {
            cy.emit(cxtEvt);
          }
          r.hoverData.cxtDragged = true;
          if (!r.hoverData.cxtOver || near !== r.hoverData.cxtOver) {
            if (r.hoverData.cxtOver) {
              r.hoverData.cxtOver.emit({
                originalEvent: e,
                type: 'cxtdragout',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
            r.hoverData.cxtOver = near;
            if (near) {
              near.emit({
                originalEvent: e,
                type: 'cxtdragover',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
          }
        }

        // Check if we are drag panning the entire graph
      } else if (r.hoverData.dragging) {
        preventDefault = true;
        if (cy.panningEnabled() && cy.userPanningEnabled()) {
          var deltaP;
          if (r.hoverData.justStartedPan) {
            var mdPos = r.hoverData.mdownPos;
            deltaP = {
              x: (pos[0] - mdPos[0]) * zoom,
              y: (pos[1] - mdPos[1]) * zoom
            };
            r.hoverData.justStartedPan = false;
          } else {
            deltaP = {
              x: disp[0] * zoom,
              y: disp[1] * zoom
            };
          }
          cy.panBy(deltaP);
          cy.emit('dragpan');
          r.hoverData.dragged = true;
        }

        // Needs reproject due to pan changing viewport
        pos = r.projectIntoViewport(e.clientX, e.clientY);

        // Checks primary button down & out of time & mouse not moved much
      } else if (select[4] == 1 && (down == null || down.pannable())) {
        if (isOverThresholdDrag) {
          if (!r.hoverData.dragging && cy.boxSelectionEnabled() && (multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled())) {
            goIntoBoxMode();
          } else if (!r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled()) {
            var allowPassthrough = allowPanningPassthrough(down, r.hoverData.downs);
            if (allowPassthrough) {
              r.hoverData.dragging = true;
              r.hoverData.justStartedPan = true;
              select[4] = 0;
              r.data.bgActivePosistion = array2point(mdownPos);
              r.redrawHint('select', true);
              r.redraw();
            }
          }
          if (down && down.pannable() && down.active()) {
            down.unactivate();
          }
        }
      } else {
        if (down && down.pannable() && down.active()) {
          down.unactivate();
        }
        if ((!down || !down.grabbed()) && near != last) {
          if (last) {
            triggerEvents(last, ['mouseout', 'tapdragout'], e, {
              x: pos[0],
              y: pos[1]
            });
          }
          if (near) {
            triggerEvents(near, ['mouseover', 'tapdragover'], e, {
              x: pos[0],
              y: pos[1]
            });
          }
          r.hoverData.last = near;
        }
        if (down) {
          if (isOverThresholdDrag) {
            // then we can take action

            if (cy.boxSelectionEnabled() && multSelKeyDown) {
              // then selection overrides
              if (down && down.grabbed()) {
                freeDraggedElements(draggedElements);
                down.emit('freeon');
                draggedElements.emit('free');
                if (r.dragData.didDrag) {
                  down.emit('dragfreeon');
                  draggedElements.emit('dragfree');
                }
              }
              goIntoBoxMode();
            } else if (down && down.grabbed() && r.nodeIsDraggable(down)) {
              // drag node
              var justStartedDrag = !r.dragData.didDrag;
              if (justStartedDrag) {
                r.redrawHint('eles', true);
              }
              r.dragData.didDrag = true; // indicate that we actually did drag the node

              // now, add the elements to the drag layer if not done already
              if (!r.hoverData.draggingEles) {
                addNodesToDrag(draggedElements, {
                  inDragLayer: true
                });
              }
              var totalShift = {
                x: 0,
                y: 0
              };
              if (number$1(disp[0]) && number$1(disp[1])) {
                totalShift.x += disp[0];
                totalShift.y += disp[1];
                if (justStartedDrag) {
                  var dragDelta = r.hoverData.dragDelta;
                  if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {
                    totalShift.x += dragDelta[0];
                    totalShift.y += dragDelta[1];
                  }
                }
              }
              r.hoverData.draggingEles = true;
              draggedElements.silentShift(totalShift).emit('position drag');
              r.redrawHint('drag', true);
              r.redraw();
            }
          } else {
            // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant
            updateDragDelta();
          }
        }

        // prevent the dragging from triggering text selection on the page
        preventDefault = true;
      }
      select[2] = pos[0];
      select[3] = pos[1];
      if (preventDefault) {
        if (e.stopPropagation) e.stopPropagation();
        if (e.preventDefault) e.preventDefault();
        return false;
      }
    }, false);
    var clickTimeout, didDoubleClick, prevClickTimeStamp;
    r.registerBinding(containerWindow, 'mouseup', function mouseupHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.hoverData.capture;
      if (!capture) {
        return;
      }
      r.hoverData.capture = false;
      var cy = r.cy;
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      var select = r.selection;
      var near = r.findNearestElement(pos[0], pos[1], true, false);
      var draggedElements = r.dragData.possibleDragElements;
      var down = r.hoverData.down;
      var multSelKeyDown = isMultSelKeyDown(e);
      if (r.data.bgActivePosistion) {
        r.redrawHint('select', true);
        r.redraw();
      }
      r.hoverData.tapholdCancelled = true;
      r.data.bgActivePosistion = undefined; // not active bg now

      if (down) {
        down.unactivate();
      }
      if (r.hoverData.which === 3) {
        var cxtEvt = {
          originalEvent: e,
          type: 'cxttapend',
          position: {
            x: pos[0],
            y: pos[1]
          }
        };
        if (down) {
          down.emit(cxtEvt);
        } else {
          cy.emit(cxtEvt);
        }
        if (!r.hoverData.cxtDragged) {
          var cxtTap = {
            originalEvent: e,
            type: 'cxttap',
            position: {
              x: pos[0],
              y: pos[1]
            }
          };
          if (down) {
            down.emit(cxtTap);
          } else {
            cy.emit(cxtTap);
          }
        }
        r.hoverData.cxtDragged = false;
        r.hoverData.which = null;
      } else if (r.hoverData.which === 1) {
        triggerEvents(near, ['mouseup', 'tapend', 'vmouseup'], e, {
          x: pos[0],
          y: pos[1]
        });
        if (!r.dragData.didDrag &&
        // didn't move a node around
        !r.hoverData.dragged &&
        // didn't pan
        !r.hoverData.selecting &&
        // not box selection
        !r.hoverData.isOverThresholdDrag // didn't move too much
        ) {
          triggerEvents(down, ["click", "tap", "vclick"], e, {
            x: pos[0],
            y: pos[1]
          });
          didDoubleClick = false;
          if (e.timeStamp - prevClickTimeStamp <= cy.multiClickDebounceTime()) {
            clickTimeout && clearTimeout(clickTimeout);
            didDoubleClick = true;
            prevClickTimeStamp = null;
            triggerEvents(down, ["dblclick", "dbltap", "vdblclick"], e, {
              x: pos[0],
              y: pos[1]
            });
          } else {
            clickTimeout = setTimeout(function () {
              if (didDoubleClick) return;
              triggerEvents(down, ["oneclick", "onetap", "voneclick"], e, {
                x: pos[0],
                y: pos[1]
              });
            }, cy.multiClickDebounceTime());
            prevClickTimeStamp = e.timeStamp;
          }
        }

        // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something
        if (down == null // not mousedown on node
        && !r.dragData.didDrag // didn't move the node around
        && !r.hoverData.selecting // not box selection
        && !r.hoverData.dragged // didn't pan
        && !isMultSelKeyDown(e)) {
          cy.$(isSelected).unselect(['tapunselect']);
          if (draggedElements.length > 0) {
            r.redrawHint('eles', true);
          }
          r.dragData.possibleDragElements = draggedElements = cy.collection();
        }

        // Single selection
        if (near == down && !r.dragData.didDrag && !r.hoverData.selecting) {
          if (near != null && near._private.selectable) {
            if (r.hoverData.dragging) ; else if (cy.selectionType() === 'additive' || multSelKeyDown) {
              if (near.selected()) {
                near.unselect(['tapunselect']);
              } else {
                near.select(['tapselect']);
              }
            } else {
              if (!multSelKeyDown) {
                cy.$(isSelected).unmerge(near).unselect(['tapunselect']);
                near.select(['tapselect']);
              }
            }
            r.redrawHint('eles', true);
          }
        }
        if (r.hoverData.selecting) {
          var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));
          r.redrawHint('select', true);
          if (box.length > 0) {
            r.redrawHint('eles', true);
          }
          cy.emit({
            type: 'boxend',
            originalEvent: e,
            position: {
              x: pos[0],
              y: pos[1]
            }
          });
          var eleWouldBeSelected = function eleWouldBeSelected(ele) {
            return ele.selectable() && !ele.selected();
          };
          if (cy.selectionType() === 'additive') {
            box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
          } else {
            if (!multSelKeyDown) {
              cy.$(isSelected).unmerge(box).unselect();
            }
            box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
          }

          // always need redraw in case eles unselectable
          r.redraw();
        }

        // Cancel drag pan
        if (r.hoverData.dragging) {
          r.hoverData.dragging = false;
          r.redrawHint('select', true);
          r.redrawHint('eles', true);
          r.redraw();
        }
        if (!select[4]) {
          r.redrawHint('drag', true);
          r.redrawHint('eles', true);
          var downWasGrabbed = down && down.grabbed();
          freeDraggedElements(draggedElements);
          if (downWasGrabbed) {
            down.emit('freeon');
            draggedElements.emit('free');
            if (r.dragData.didDrag) {
              down.emit('dragfreeon');
              draggedElements.emit('dragfree');
            }
          }
        }
      } // else not right mouse

      select[4] = 0;
      r.hoverData.down = null;
      r.hoverData.cxtStarted = false;
      r.hoverData.draggingEles = false;
      r.hoverData.selecting = false;
      r.hoverData.isOverThresholdDrag = false;
      r.dragData.didDrag = false;
      r.hoverData.dragged = false;
      r.hoverData.dragDelta = [];
      r.hoverData.mdownPos = null;
      r.hoverData.mdownGPos = null;
    }, false);
    var wheelHandler = function wheelHandler(e) {
      if (r.scrollingPage) {
        return;
      } // while scrolling, ignore wheel-to-zoom

      var cy = r.cy;
      var zoom = cy.zoom();
      var pan = cy.pan();
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      var rpos = [pos[0] * zoom + pan.x, pos[1] * zoom + pan.y];
      if (r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection()) {
        // if pan dragging or cxt dragging, wheel movements make no zoom
        e.preventDefault();
        return;
      }
      if (cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled()) {
        e.preventDefault();
        r.data.wheelZooming = true;
        clearTimeout(r.data.wheelTimeout);
        r.data.wheelTimeout = setTimeout(function () {
          r.data.wheelZooming = false;
          r.redrawHint('eles', true);
          r.redraw();
        }, 150);
        var diff;
        if (e.deltaY != null) {
          diff = e.deltaY / -250;
        } else if (e.wheelDeltaY != null) {
          diff = e.wheelDeltaY / 1000;
        } else {
          diff = e.wheelDelta / 1000;
        }
        diff = diff * r.wheelSensitivity;
        var needsWheelFix = e.deltaMode === 1;
        if (needsWheelFix) {
          // fixes slow wheel events on ff/linux and ff/windows
          diff *= 33;
        }
        var newZoom = cy.zoom() * Math.pow(10, diff);
        if (e.type === 'gesturechange') {
          newZoom = r.gestureStartZoom * e.scale;
        }
        cy.zoom({
          level: newZoom,
          renderedPosition: {
            x: rpos[0],
            y: rpos[1]
          }
        });
        cy.emit(e.type === 'gesturechange' ? 'pinchzoom' : 'scrollzoom');
      }
    };

    // Functions to help with whether mouse wheel should trigger zooming
    // --
    r.registerBinding(r.container, 'wheel', wheelHandler, true);

    // disable nonstandard wheel events
    // r.registerBinding(r.container, 'mousewheel', wheelHandler, true);
    // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);
    // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox

    r.registerBinding(containerWindow, 'scroll', function scrollHandler(e) {
      // eslint-disable-line no-unused-vars
      r.scrollingPage = true;
      clearTimeout(r.scrollingPageTimeout);
      r.scrollingPageTimeout = setTimeout(function () {
        r.scrollingPage = false;
      }, 250);
    }, true);

    // desktop safari pinch to zoom start
    r.registerBinding(r.container, 'gesturestart', function gestureStartHandler(e) {
      r.gestureStartZoom = r.cy.zoom();
      if (!r.hasTouchStarted) {
        // don't affect touch devices like iphone
        e.preventDefault();
      }
    }, true);
    r.registerBinding(r.container, 'gesturechange', function (e) {
      if (!r.hasTouchStarted) {
        // don't affect touch devices like iphone
        wheelHandler(e);
      }
    }, true);

    // Functions to help with handling mouseout/mouseover on the Cytoscape container
    // Handle mouseout on Cytoscape container
    r.registerBinding(r.container, 'mouseout', function mouseOutHandler(e) {
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      r.cy.emit({
        originalEvent: e,
        type: 'mouseout',
        position: {
          x: pos[0],
          y: pos[1]
        }
      });
    }, false);
    r.registerBinding(r.container, 'mouseover', function mouseOverHandler(e) {
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      r.cy.emit({
        originalEvent: e,
        type: 'mouseover',
        position: {
          x: pos[0],
          y: pos[1]
        }
      });
    }, false);
    var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom
    var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom
    var center1, modelCenter1; // center point on start pinch to zoom
    var offsetLeft, offsetTop;
    var containerWidth, containerHeight;
    var twoFingersStartInside;
    var distance = function distance(x1, y1, x2, y2) {
      return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    };
    var distanceSq = function distanceSq(x1, y1, x2, y2) {
      return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
    };
    var touchstartHandler;
    r.registerBinding(r.container, 'touchstart', touchstartHandler = function touchstartHandler(e) {
      r.hasTouchStarted = true;
      if (!eventInContainer(e)) {
        return;
      }
      blurActiveDomElement();
      r.touchData.capture = true;
      r.data.bgActivePosistion = undefined;
      var cy = r.cy;
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }

      // record starting points for pinch-to-zoom
      if (e.touches[1]) {
        r.touchData.singleTouchMoved = true;
        freeDraggedElements(r.dragData.touchDragEles);
        var offsets = r.findContainerClientCoords();
        offsetLeft = offsets[0];
        offsetTop = offsets[1];
        containerWidth = offsets[2];
        containerHeight = offsets[3];
        f1x1 = e.touches[0].clientX - offsetLeft;
        f1y1 = e.touches[0].clientY - offsetTop;
        f2x1 = e.touches[1].clientX - offsetLeft;
        f2y1 = e.touches[1].clientY - offsetTop;
        twoFingersStartInside = 0 <= f1x1 && f1x1 <= containerWidth && 0 <= f2x1 && f2x1 <= containerWidth && 0 <= f1y1 && f1y1 <= containerHeight && 0 <= f2y1 && f2y1 <= containerHeight;
        var pan = cy.pan();
        var zoom = cy.zoom();
        distance1 = distance(f1x1, f1y1, f2x1, f2y1);
        distance1Sq = distanceSq(f1x1, f1y1, f2x1, f2y1);
        center1 = [(f1x1 + f2x1) / 2, (f1y1 + f2y1) / 2];
        modelCenter1 = [(center1[0] - pan.x) / zoom, (center1[1] - pan.y) / zoom];

        // consider context tap
        var cxtDistThreshold = 200;
        var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold;
        if (distance1Sq < cxtDistThresholdSq && !e.touches[2]) {
          var near1 = r.findNearestElement(now[0], now[1], true, true);
          var near2 = r.findNearestElement(now[2], now[3], true, true);
          if (near1 && near1.isNode()) {
            near1.activate().emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
            r.touchData.start = near1;
          } else if (near2 && near2.isNode()) {
            near2.activate().emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
            r.touchData.start = near2;
          } else {
            cy.emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
          if (r.touchData.start) {
            r.touchData.start._private.grabbed = false;
          }
          r.touchData.cxt = true;
          r.touchData.cxtDragged = false;
          r.data.bgActivePosistion = undefined;
          r.redraw();
          return;
        }
      }
      if (e.touches[2]) {
        // ignore

        // safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...)
        if (cy.boxSelectionEnabled()) {
          e.preventDefault();
        }
      } else if (e.touches[1]) ; else if (e.touches[0]) {
        var nears = r.findNearestElements(now[0], now[1], true, true);
        var near = nears[0];
        if (near != null) {
          near.activate();
          r.touchData.start = near;
          r.touchData.starts = nears;
          if (r.nodeIsGrabbable(near)) {
            var draggedEles = r.dragData.touchDragEles = cy.collection();
            var selectedNodes = null;
            r.redrawHint('eles', true);
            r.redrawHint('drag', true);
            if (near.selected()) {
              // reset drag elements, since near will be added again

              selectedNodes = cy.$(function (ele) {
                return ele.selected() && r.nodeIsGrabbable(ele);
              });
              addNodesToDrag(selectedNodes, {
                addToList: draggedEles
              });
            } else {
              addNodeToDrag(near, {
                addToList: draggedEles
              });
            }
            setGrabTarget(near);
            var makeEvent = function makeEvent(type) {
              return {
                originalEvent: e,
                type: type,
                position: {
                  x: now[0],
                  y: now[1]
                }
              };
            };
            near.emit(makeEvent('grabon'));
            if (selectedNodes) {
              selectedNodes.forEach(function (n) {
                n.emit(makeEvent('grab'));
              });
            } else {
              near.emit(makeEvent('grab'));
            }
          }
        }
        triggerEvents(near, ['touchstart', 'tapstart', 'vmousedown'], e, {
          x: now[0],
          y: now[1]
        });
        if (near == null) {
          r.data.bgActivePosistion = {
            x: pos[0],
            y: pos[1]
          };
          r.redrawHint('select', true);
          r.redraw();
        }

        // Tap, taphold
        // -----

        r.touchData.singleTouchMoved = false;
        r.touchData.singleTouchStartTime = +new Date();
        clearTimeout(r.touchData.tapholdTimeout);
        r.touchData.tapholdTimeout = setTimeout(function () {
          if (r.touchData.singleTouchMoved === false && !r.pinching // if pinching, then taphold unselect shouldn't take effect
          && !r.touchData.selecting // box selection shouldn't allow taphold through
          ) {
            triggerEvents(r.touchData.start, ['taphold'], e, {
              x: now[0],
              y: now[1]
            });
          }
        }, r.tapholdDuration);
      }
      if (e.touches.length >= 1) {
        var sPos = r.touchData.startPosition = [null, null, null, null, null, null];
        for (var i = 0; i < now.length; i++) {
          sPos[i] = earlier[i] = now[i];
        }
        var touch0 = e.touches[0];
        r.touchData.startGPosition = [touch0.clientX, touch0.clientY];
      }
    }, false);
    var touchmoveHandler;
    r.registerBinding(window, 'touchmove', touchmoveHandler = function touchmoveHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.touchData.capture;
      if (!capture && !eventInContainer(e)) {
        return;
      }
      var select = r.selection;
      var cy = r.cy;
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      var zoom = cy.zoom();
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }
      var startGPos = r.touchData.startGPosition;
      var isOverThresholdDrag;
      if (capture && e.touches[0] && startGPos) {
        var disp = [];
        for (var j = 0; j < now.length; j++) {
          disp[j] = now[j] - earlier[j];
        }
        var dx = e.touches[0].clientX - startGPos[0];
        var dx2 = dx * dx;
        var dy = e.touches[0].clientY - startGPos[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        isOverThresholdDrag = dist2 >= r.touchTapThreshold2;
      }

      // context swipe cancelling
      if (capture && r.touchData.cxt) {
        e.preventDefault();
        var f1x2 = e.touches[0].clientX - offsetLeft,
          f1y2 = e.touches[0].clientY - offsetTop;
        var f2x2 = e.touches[1].clientX - offsetLeft,
          f2y2 = e.touches[1].clientY - offsetTop;
        // var distance2 = distance( f1x2, f1y2, f2x2, f2y2 );
        var distance2Sq = distanceSq(f1x2, f1y2, f2x2, f2y2);
        var factorSq = distance2Sq / distance1Sq;
        var distThreshold = 150;
        var distThresholdSq = distThreshold * distThreshold;
        var factorThreshold = 1.5;
        var factorThresholdSq = factorThreshold * factorThreshold;

        // cancel ctx gestures if the distance b/t the fingers increases
        if (factorSq >= factorThresholdSq || distance2Sq >= distThresholdSq) {
          r.touchData.cxt = false;
          r.data.bgActivePosistion = undefined;
          r.redrawHint('select', true);
          var cxtEvt = {
            originalEvent: e,
            type: 'cxttapend',
            position: {
              x: now[0],
              y: now[1]
            }
          };
          if (r.touchData.start) {
            r.touchData.start.unactivate().emit(cxtEvt);
            r.touchData.start = null;
          } else {
            cy.emit(cxtEvt);
          }
        }
      }

      // context swipe
      if (capture && r.touchData.cxt) {
        var cxtEvt = {
          originalEvent: e,
          type: 'cxtdrag',
          position: {
            x: now[0],
            y: now[1]
          }
        };
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        if (r.touchData.start) {
          r.touchData.start.emit(cxtEvt);
        } else {
          cy.emit(cxtEvt);
        }
        if (r.touchData.start) {
          r.touchData.start._private.grabbed = false;
        }
        r.touchData.cxtDragged = true;
        var near = r.findNearestElement(now[0], now[1], true, true);
        if (!r.touchData.cxtOver || near !== r.touchData.cxtOver) {
          if (r.touchData.cxtOver) {
            r.touchData.cxtOver.emit({
              originalEvent: e,
              type: 'cxtdragout',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
          r.touchData.cxtOver = near;
          if (near) {
            near.emit({
              originalEvent: e,
              type: 'cxtdragover',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
        }

        // box selection
      } else if (capture && e.touches[2] && cy.boxSelectionEnabled()) {
        e.preventDefault();
        r.data.bgActivePosistion = undefined;
        this.lastThreeTouch = +new Date();
        if (!r.touchData.selecting) {
          cy.emit({
            originalEvent: e,
            type: 'boxstart',
            position: {
              x: now[0],
              y: now[1]
            }
          });
        }
        r.touchData.selecting = true;
        r.touchData.didSelect = true;
        select[4] = 1;
        if (!select || select.length === 0 || select[0] === undefined) {
          select[0] = (now[0] + now[2] + now[4]) / 3;
          select[1] = (now[1] + now[3] + now[5]) / 3;
          select[2] = (now[0] + now[2] + now[4]) / 3 + 1;
          select[3] = (now[1] + now[3] + now[5]) / 3 + 1;
        } else {
          select[2] = (now[0] + now[2] + now[4]) / 3;
          select[3] = (now[1] + now[3] + now[5]) / 3;
        }
        r.redrawHint('select', true);
        r.redraw();

        // pinch to zoom
      } else if (capture && e.touches[1] && !r.touchData.didSelect // don't allow box selection to degrade to pinch-to-zoom
      && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled()) {
        // two fingers => pinch to zoom
        e.preventDefault();
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        var draggedEles = r.dragData.touchDragEles;
        if (draggedEles) {
          r.redrawHint('drag', true);
          for (var i = 0; i < draggedEles.length; i++) {
            var de_p = draggedEles[i]._private;
            de_p.grabbed = false;
            de_p.rscratch.inDragLayer = false;
          }
        }
        var _start = r.touchData.start;

        // (x2, y2) for fingers 1 and 2
        var f1x2 = e.touches[0].clientX - offsetLeft,
          f1y2 = e.touches[0].clientY - offsetTop;
        var f2x2 = e.touches[1].clientX - offsetLeft,
          f2y2 = e.touches[1].clientY - offsetTop;
        var distance2 = distance(f1x2, f1y2, f2x2, f2y2);
        // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 );
        // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq );
        var factor = distance2 / distance1;
        if (twoFingersStartInside) {
          // delta finger1
          var df1x = f1x2 - f1x1;
          var df1y = f1y2 - f1y1;

          // delta finger 2
          var df2x = f2x2 - f2x1;
          var df2y = f2y2 - f2y1;

          // translation is the normalised vector of the two fingers movement
          // i.e. so pinching cancels out and moving together pans
          var tx = (df1x + df2x) / 2;
          var ty = (df1y + df2y) / 2;

          // now calculate the zoom
          var zoom1 = cy.zoom();
          var zoom2 = zoom1 * factor;
          var pan1 = cy.pan();

          // the model center point converted to the current rendered pos
          var ctrx = modelCenter1[0] * zoom1 + pan1.x;
          var ctry = modelCenter1[1] * zoom1 + pan1.y;
          var pan2 = {
            x: -zoom2 / zoom1 * (ctrx - pan1.x - tx) + ctrx,
            y: -zoom2 / zoom1 * (ctry - pan1.y - ty) + ctry
          };

          // remove dragged eles
          if (_start && _start.active()) {
            var draggedEles = r.dragData.touchDragEles;
            freeDraggedElements(draggedEles);
            r.redrawHint('drag', true);
            r.redrawHint('eles', true);
            _start.unactivate().emit('freeon');
            draggedEles.emit('free');
            if (r.dragData.didDrag) {
              _start.emit('dragfreeon');
              draggedEles.emit('dragfree');
            }
          }
          cy.viewport({
            zoom: zoom2,
            pan: pan2,
            cancelOnFailedZoom: true
          });
          cy.emit('pinchzoom');
          distance1 = distance2;
          f1x1 = f1x2;
          f1y1 = f1y2;
          f2x1 = f2x2;
          f2y1 = f2y2;
          r.pinching = true;
        }

        // Re-project
        if (e.touches[0]) {
          var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
          now[0] = pos[0];
          now[1] = pos[1];
        }
        if (e.touches[1]) {
          var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
          now[2] = pos[0];
          now[3] = pos[1];
        }
        if (e.touches[2]) {
          var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
          now[4] = pos[0];
          now[5] = pos[1];
        }
      } else if (e.touches[0] && !r.touchData.didSelect // don't allow box selection to degrade to single finger events like panning
      ) {
        var start = r.touchData.start;
        var last = r.touchData.last;
        var near;
        if (!r.hoverData.draggingEles && !r.swipePanning) {
          near = r.findNearestElement(now[0], now[1], true, true);
        }
        if (capture && start != null) {
          e.preventDefault();
        }

        // dragging nodes
        if (capture && start != null && r.nodeIsDraggable(start)) {
          if (isOverThresholdDrag) {
            // then dragging can happen
            var draggedEles = r.dragData.touchDragEles;
            var justStartedDrag = !r.dragData.didDrag;
            if (justStartedDrag) {
              addNodesToDrag(draggedEles, {
                inDragLayer: true
              });
            }
            r.dragData.didDrag = true;
            var totalShift = {
              x: 0,
              y: 0
            };
            if (number$1(disp[0]) && number$1(disp[1])) {
              totalShift.x += disp[0];
              totalShift.y += disp[1];
              if (justStartedDrag) {
                r.redrawHint('eles', true);
                var dragDelta = r.touchData.dragDelta;
                if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {
                  totalShift.x += dragDelta[0];
                  totalShift.y += dragDelta[1];
                }
              }
            }
            r.hoverData.draggingEles = true;
            draggedEles.silentShift(totalShift).emit('position drag');
            r.redrawHint('drag', true);
            if (r.touchData.startPosition[0] == earlier[0] && r.touchData.startPosition[1] == earlier[1]) {
              r.redrawHint('eles', true);
            }
            r.redraw();
          } else {
            // otherwise keep track of drag delta for later
            var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || [];
            if (dragDelta.length === 0) {
              dragDelta.push(disp[0]);
              dragDelta.push(disp[1]);
            } else {
              dragDelta[0] += disp[0];
              dragDelta[1] += disp[1];
            }
          }
        }

        // touchmove
        {
          triggerEvents(start || near, ['touchmove', 'tapdrag', 'vmousemove'], e, {
            x: now[0],
            y: now[1]
          });
          if ((!start || !start.grabbed()) && near != last) {
            if (last) {
              last.emit({
                originalEvent: e,
                type: 'tapdragout',
                position: {
                  x: now[0],
                  y: now[1]
                }
              });
            }
            if (near) {
              near.emit({
                originalEvent: e,
                type: 'tapdragover',
                position: {
                  x: now[0],
                  y: now[1]
                }
              });
            }
          }
          r.touchData.last = near;
        }

        // check to cancel taphold
        if (capture) {
          for (var i = 0; i < now.length; i++) {
            if (now[i] && r.touchData.startPosition[i] && isOverThresholdDrag) {
              r.touchData.singleTouchMoved = true;
            }
          }
        }

        // panning
        if (capture && (start == null || start.pannable()) && cy.panningEnabled() && cy.userPanningEnabled()) {
          var allowPassthrough = allowPanningPassthrough(start, r.touchData.starts);
          if (allowPassthrough) {
            e.preventDefault();
            if (!r.data.bgActivePosistion) {
              r.data.bgActivePosistion = array2point(r.touchData.startPosition);
            }
            if (r.swipePanning) {
              cy.panBy({
                x: disp[0] * zoom,
                y: disp[1] * zoom
              });
              cy.emit('dragpan');
            } else if (isOverThresholdDrag) {
              r.swipePanning = true;
              cy.panBy({
                x: dx * zoom,
                y: dy * zoom
              });
              cy.emit('dragpan');
              if (start) {
                start.unactivate();
                r.redrawHint('select', true);
                r.touchData.start = null;
              }
            }
          }

          // Re-project
          var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
          now[0] = pos[0];
          now[1] = pos[1];
        }
      }
      for (var j = 0; j < now.length; j++) {
        earlier[j] = now[j];
      }

      // the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning
      if (capture && e.touches.length > 0 && !r.hoverData.draggingEles && !r.swipePanning && r.data.bgActivePosistion != null) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        r.redraw();
      }
    }, false);
    var touchcancelHandler;
    r.registerBinding(containerWindow, 'touchcancel', touchcancelHandler = function touchcancelHandler(e) {
      // eslint-disable-line no-unused-vars
      var start = r.touchData.start;
      r.touchData.capture = false;
      if (start) {
        start.unactivate();
      }
    });
    var touchendHandler, didDoubleTouch, touchTimeout, prevTouchTimeStamp;
    r.registerBinding(containerWindow, 'touchend', touchendHandler = function touchendHandler(e) {
      // eslint-disable-line no-unused-vars
      var start = r.touchData.start;
      var capture = r.touchData.capture;
      if (capture) {
        if (e.touches.length === 0) {
          r.touchData.capture = false;
        }
        e.preventDefault();
      } else {
        return;
      }
      var select = r.selection;
      r.swipePanning = false;
      r.hoverData.draggingEles = false;
      var cy = r.cy;
      var zoom = cy.zoom();
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }
      if (start) {
        start.unactivate();
      }
      var ctxTapend;
      if (r.touchData.cxt) {
        ctxTapend = {
          originalEvent: e,
          type: 'cxttapend',
          position: {
            x: now[0],
            y: now[1]
          }
        };
        if (start) {
          start.emit(ctxTapend);
        } else {
          cy.emit(ctxTapend);
        }
        if (!r.touchData.cxtDragged) {
          var ctxTap = {
            originalEvent: e,
            type: 'cxttap',
            position: {
              x: now[0],
              y: now[1]
            }
          };
          if (start) {
            start.emit(ctxTap);
          } else {
            cy.emit(ctxTap);
          }
        }
        if (r.touchData.start) {
          r.touchData.start._private.grabbed = false;
        }
        r.touchData.cxt = false;
        r.touchData.start = null;
        r.redraw();
        return;
      }

      // no more box selection if we don't have three fingers
      if (!e.touches[2] && cy.boxSelectionEnabled() && r.touchData.selecting) {
        r.touchData.selecting = false;
        var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));
        select[0] = undefined;
        select[1] = undefined;
        select[2] = undefined;
        select[3] = undefined;
        select[4] = 0;
        r.redrawHint('select', true);
        cy.emit({
          type: 'boxend',
          originalEvent: e,
          position: {
            x: now[0],
            y: now[1]
          }
        });
        var eleWouldBeSelected = function eleWouldBeSelected(ele) {
          return ele.selectable() && !ele.selected();
        };
        box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
        if (box.nonempty()) {
          r.redrawHint('eles', true);
        }
        r.redraw();
      }
      if (start != null) {
        start.unactivate();
      }
      if (e.touches[2]) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
      } else if (e.touches[1]) ; else if (e.touches[0]) ; else if (!e.touches[0]) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        var draggedEles = r.dragData.touchDragEles;
        if (start != null) {
          var startWasGrabbed = start._private.grabbed;
          freeDraggedElements(draggedEles);
          r.redrawHint('drag', true);
          r.redrawHint('eles', true);
          if (startWasGrabbed) {
            start.emit('freeon');
            draggedEles.emit('free');
            if (r.dragData.didDrag) {
              start.emit('dragfreeon');
              draggedEles.emit('dragfree');
            }
          }
          triggerEvents(start, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {
            x: now[0],
            y: now[1]
          });
          start.unactivate();
          r.touchData.start = null;
        } else {
          var near = r.findNearestElement(now[0], now[1], true, true);
          triggerEvents(near, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {
            x: now[0],
            y: now[1]
          });
        }
        var dx = r.touchData.startPosition[0] - now[0];
        var dx2 = dx * dx;
        var dy = r.touchData.startPosition[1] - now[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        var rdist2 = dist2 * zoom * zoom;

        // Tap event, roughly same as mouse click event for touch
        if (!r.touchData.singleTouchMoved) {
          if (!start) {
            cy.$(':selected').unselect(['tapunselect']);
          }
          triggerEvents(start, ['tap', 'vclick'], e, {
            x: now[0],
            y: now[1]
          });
          didDoubleTouch = false;
          if (e.timeStamp - prevTouchTimeStamp <= cy.multiClickDebounceTime()) {
            touchTimeout && clearTimeout(touchTimeout);
            didDoubleTouch = true;
            prevTouchTimeStamp = null;
            triggerEvents(start, ['dbltap', 'vdblclick'], e, {
              x: now[0],
              y: now[1]
            });
          } else {
            touchTimeout = setTimeout(function () {
              if (didDoubleTouch) return;
              triggerEvents(start, ['onetap', 'voneclick'], e, {
                x: now[0],
                y: now[1]
              });
            }, cy.multiClickDebounceTime());
            prevTouchTimeStamp = e.timeStamp;
          }
        }

        // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance
        if (start != null && !r.dragData.didDrag // didn't drag nodes around
        && start._private.selectable && rdist2 < r.touchTapThreshold2 && !r.pinching // pinch to zoom should not affect selection
        ) {
          if (cy.selectionType() === 'single') {
            cy.$(isSelected).unmerge(start).unselect(['tapunselect']);
            start.select(['tapselect']);
          } else {
            if (start.selected()) {
              start.unselect(['tapunselect']);
            } else {
              start.select(['tapselect']);
            }
          }
          r.redrawHint('eles', true);
        }
        r.touchData.singleTouchMoved = true;
      }
      for (var j = 0; j < now.length; j++) {
        earlier[j] = now[j];
      }
      r.dragData.didDrag = false; // reset for next touchstart

      if (e.touches.length === 0) {
        r.touchData.dragDelta = [];
        r.touchData.startPosition = [null, null, null, null, null, null];
        r.touchData.startGPosition = null;
        r.touchData.didSelect = false;
      }
      if (e.touches.length < 2) {
        if (e.touches.length === 1) {
          // the old start global pos'n may not be the same finger that remains
          r.touchData.startGPosition = [e.touches[0].clientX, e.touches[0].clientY];
        }
        r.pinching = false;
        r.redrawHint('eles', true);
        r.redraw();
      }

      //r.redraw();
    }, false);

    // fallback compatibility layer for ms pointer events
    if (typeof TouchEvent === 'undefined') {
      var pointers = [];
      var makeTouch = function makeTouch(e) {
        return {
          clientX: e.clientX,
          clientY: e.clientY,
          force: 1,
          identifier: e.pointerId,
          pageX: e.pageX,
          pageY: e.pageY,
          radiusX: e.width / 2,
          radiusY: e.height / 2,
          screenX: e.screenX,
          screenY: e.screenY,
          target: e.target
        };
      };
      var makePointer = function makePointer(e) {
        return {
          event: e,
          touch: makeTouch(e)
        };
      };
      var addPointer = function addPointer(e) {
        pointers.push(makePointer(e));
      };
      var removePointer = function removePointer(e) {
        for (var i = 0; i < pointers.length; i++) {
          var p = pointers[i];
          if (p.event.pointerId === e.pointerId) {
            pointers.splice(i, 1);
            return;
          }
        }
      };
      var updatePointer = function updatePointer(e) {
        var p = pointers.filter(function (p) {
          return p.event.pointerId === e.pointerId;
        })[0];
        p.event = e;
        p.touch = makeTouch(e);
      };
      var addTouchesToEvent = function addTouchesToEvent(e) {
        e.touches = pointers.map(function (p) {
          return p.touch;
        });
      };
      var pointerIsMouse = function pointerIsMouse(e) {
        return e.pointerType === 'mouse' || e.pointerType === 4;
      };
      r.registerBinding(r.container, 'pointerdown', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        e.preventDefault();
        addPointer(e);
        addTouchesToEvent(e);
        touchstartHandler(e);
      });
      r.registerBinding(r.container, 'pointerup', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        removePointer(e);
        addTouchesToEvent(e);
        touchendHandler(e);
      });
      r.registerBinding(r.container, 'pointercancel', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        removePointer(e);
        addTouchesToEvent(e);
        touchcancelHandler(e);
      });
      r.registerBinding(r.container, 'pointermove', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        e.preventDefault();
        updatePointer(e);
        addTouchesToEvent(e);
        touchmoveHandler(e);
      });
    }
  };

  var BRp$2 = {};
  BRp$2.generatePolygon = function (name, points) {
    return this.nodeShapes[name] = {
      renderer: this,
      name: name,
      points: points,
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl('polygon', context, centerX, centerY, width, height, this.points);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return polygonIntersectLine(x, y, this.points, nodeX, nodeY, width / 2, height / 2, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return pointInsidePolygon(x, y, this.points, centerX, centerY, width, height, [0, -1], padding);
      }
    };
  };
  BRp$2.generateEllipse = function () {
    return this.nodeShapes['ellipse'] = {
      renderer: this,
      name: 'ellipse',
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return intersectLineEllipse(x, y, nodeX, nodeY, width / 2 + padding, height / 2 + padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return checkInEllipse(x, y, width, height, centerX, centerY, padding);
      }
    };
  };
  BRp$2.generateRoundPolygon = function (name, points) {
    // Pre-compute control points
    // Since these points depend on the radius length (which in turns depend on the width/height of the node) we will only pre-compute
    // the unit vectors.
    // For simplicity the layout will be:
    // [ p0, UnitVectorP0P1, p1, UniVectorP1P2, ..., pn, UnitVectorPnP0 ]
    var allPoints = new Array(points.length * 2);
    for (var i = 0; i < points.length / 2; i++) {
      var sourceIndex = i * 2;
      var destIndex = void 0;
      if (i < points.length / 2 - 1) {
        destIndex = (i + 1) * 2;
      } else {
        destIndex = 0;
      }
      allPoints[i * 4] = points[sourceIndex];
      allPoints[i * 4 + 1] = points[sourceIndex + 1];
      var xDest = points[destIndex] - points[sourceIndex];
      var yDest = points[destIndex + 1] - points[sourceIndex + 1];
      var norm = Math.sqrt(xDest * xDest + yDest * yDest);
      allPoints[i * 4 + 2] = xDest / norm;
      allPoints[i * 4 + 3] = yDest / norm;
    }
    return this.nodeShapes[name] = {
      renderer: this,
      name: name,
      points: allPoints,
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl('round-polygon', context, centerX, centerY, width, height, this.points);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return roundPolygonIntersectLine(x, y, this.points, nodeX, nodeY, width, height);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return pointInsideRoundPolygon(x, y, this.points, centerX, centerY, width, height);
      }
    };
  };
  BRp$2.generateRoundRectangle = function () {
    return this.nodeShapes['round-rectangle'] = this.nodeShapes['roundrectangle'] = {
      renderer: this,
      name: 'round-rectangle',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var cornerRadius = getRoundRectangleRadius(width, height);
        var diam = cornerRadius * 2;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {
          return true;
        }

        // Check top left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY - height / 2 + cornerRadius, padding)) {
          return true;
        }

        // Check top right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY - height / 2 + cornerRadius, padding)) {
          return true;
        }

        // Check bottom right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }

        // Check bottom left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }
        return false;
      }
    };
  };
  BRp$2.generateCutRectangle = function () {
    return this.nodeShapes['cut-rectangle'] = this.nodeShapes['cutrectangle'] = {
      renderer: this,
      name: 'cut-rectangle',
      cornerLength: getCutRectangleCornerLength(),
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      generateCutTrianglePts: function generateCutTrianglePts(width, height, centerX, centerY) {
        var cl = this.cornerLength;
        var hh = height / 2;
        var hw = width / 2;
        var xBegin = centerX - hw;
        var xEnd = centerX + hw;
        var yBegin = centerY - hh;
        var yEnd = centerY + hh;

        // points are in clockwise order, inner (imaginary) triangle pt on [4, 5]
        return {
          topLeft: [xBegin, yBegin + cl, xBegin + cl, yBegin, xBegin + cl, yBegin + cl],
          topRight: [xEnd - cl, yBegin, xEnd, yBegin + cl, xEnd - cl, yBegin + cl],
          bottomRight: [xEnd, yEnd - cl, xEnd - cl, yEnd, xEnd - cl, yEnd - cl],
          bottomLeft: [xBegin + cl, yEnd, xBegin, yEnd - cl, xBegin + cl, yEnd - cl]
        };
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        var cPts = this.generateCutTrianglePts(width + 2 * padding, height + 2 * padding, nodeX, nodeY);
        var pts = [].concat.apply([], [cPts.topLeft.splice(0, 4), cPts.topRight.splice(0, 4), cPts.bottomRight.splice(0, 4), cPts.bottomLeft.splice(0, 4)]);
        return polygonIntersectLine(x, y, pts, nodeX, nodeY);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * this.cornerLength, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * this.cornerLength, height, [0, -1], padding)) {
          return true;
        }
        var cutTrianglePts = this.generateCutTrianglePts(width, height, centerX, centerY);
        return pointInsidePolygonPoints(x, y, cutTrianglePts.topLeft) || pointInsidePolygonPoints(x, y, cutTrianglePts.topRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomLeft);
      }
    };
  };
  BRp$2.generateBarrel = function () {
    return this.nodeShapes['barrel'] = {
      renderer: this,
      name: 'barrel',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        // use two fixed t values for the bezier curve approximation

        var t0 = 0.15;
        var t1 = 0.5;
        var t2 = 0.85;
        var bPts = this.generateBarrelBezierPts(width + 2 * padding, height + 2 * padding, nodeX, nodeY);
        var approximateBarrelCurvePts = function approximateBarrelCurvePts(pts) {
          // approximate curve pts based on the two t values
          var m0 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t0);
          var m1 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t1);
          var m2 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t2);
          return [pts[0], pts[1], m0.x, m0.y, m1.x, m1.y, m2.x, m2.y, pts[4], pts[5]];
        };
        var pts = [].concat(approximateBarrelCurvePts(bPts.topLeft), approximateBarrelCurvePts(bPts.topRight), approximateBarrelCurvePts(bPts.bottomRight), approximateBarrelCurvePts(bPts.bottomLeft));
        return polygonIntersectLine(x, y, pts, nodeX, nodeY);
      },
      generateBarrelBezierPts: function generateBarrelBezierPts(width, height, centerX, centerY) {
        var hh = height / 2;
        var hw = width / 2;
        var xBegin = centerX - hw;
        var xEnd = centerX + hw;
        var yBegin = centerY - hh;
        var yEnd = centerY + hh;
        var curveConstants = getBarrelCurveConstants(width, height);
        var hOffset = curveConstants.heightOffset;
        var wOffset = curveConstants.widthOffset;
        var ctrlPtXOffset = curveConstants.ctrlPtOffsetPct * width;

        // points are in clockwise order, inner (imaginary) control pt on [4, 5]
        var pts = {
          topLeft: [xBegin, yBegin + hOffset, xBegin + ctrlPtXOffset, yBegin, xBegin + wOffset, yBegin],
          topRight: [xEnd - wOffset, yBegin, xEnd - ctrlPtXOffset, yBegin, xEnd, yBegin + hOffset],
          bottomRight: [xEnd, yEnd - hOffset, xEnd - ctrlPtXOffset, yEnd, xEnd - wOffset, yEnd],
          bottomLeft: [xBegin + wOffset, yEnd, xBegin + ctrlPtXOffset, yEnd, xBegin, yEnd - hOffset]
        };
        pts.topLeft.isTop = true;
        pts.topRight.isTop = true;
        pts.bottomLeft.isBottom = true;
        pts.bottomRight.isBottom = true;
        return pts;
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var curveConstants = getBarrelCurveConstants(width, height);
        var hOffset = curveConstants.heightOffset;
        var wOffset = curveConstants.widthOffset;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * hOffset, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * wOffset, height, [0, -1], padding)) {
          return true;
        }
        var barrelCurvePts = this.generateBarrelBezierPts(width, height, centerX, centerY);
        var getCurveT = function getCurveT(x, y, curvePts) {
          var x0 = curvePts[4];
          var x1 = curvePts[2];
          var x2 = curvePts[0];
          var y0 = curvePts[5];
          // var y1 = curvePts[ 3 ];
          var y2 = curvePts[1];
          var xMin = Math.min(x0, x2);
          var xMax = Math.max(x0, x2);
          var yMin = Math.min(y0, y2);
          var yMax = Math.max(y0, y2);
          if (xMin <= x && x <= xMax && yMin <= y && y <= yMax) {
            var coeff = bezierPtsToQuadCoeff(x0, x1, x2);
            var roots = solveQuadratic(coeff[0], coeff[1], coeff[2], x);
            var validRoots = roots.filter(function (r) {
              return 0 <= r && r <= 1;
            });
            if (validRoots.length > 0) {
              return validRoots[0];
            }
          }
          return null;
        };
        var curveRegions = Object.keys(barrelCurvePts);
        for (var i = 0; i < curveRegions.length; i++) {
          var corner = curveRegions[i];
          var cornerPts = barrelCurvePts[corner];
          var t = getCurveT(x, y, cornerPts);
          if (t == null) {
            continue;
          }
          var y0 = cornerPts[5];
          var y1 = cornerPts[3];
          var y2 = cornerPts[1];
          var bezY = qbezierAt(y0, y1, y2, t);
          if (cornerPts.isTop && bezY <= y) {
            return true;
          }
          if (cornerPts.isBottom && y <= bezY) {
            return true;
          }
        }
        return false;
      }
    };
  };
  BRp$2.generateBottomRoundrectangle = function () {
    return this.nodeShapes['bottom-round-rectangle'] = this.nodeShapes['bottomroundrectangle'] = {
      renderer: this,
      name: 'bottom-round-rectangle',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        var topStartX = nodeX - (width / 2 + padding);
        var topStartY = nodeY - (height / 2 + padding);
        var topEndY = topStartY;
        var topEndX = nodeX + (width / 2 + padding);
        var topIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);
        if (topIntersections.length > 0) {
          return topIntersections;
        }
        return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var cornerRadius = getRoundRectangleRadius(width, height);
        var diam = 2 * cornerRadius;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {
          return true;
        }

        // check non-rounded top side
        var outerWidth = width / 2 + 2 * padding;
        var outerHeight = height / 2 + 2 * padding;
        var points = [centerX - outerWidth, centerY - outerHeight, centerX - outerWidth, centerY, centerX + outerWidth, centerY, centerX + outerWidth, centerY - outerHeight];
        if (pointInsidePolygonPoints(x, y, points)) {
          return true;
        }

        // Check bottom right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }

        // Check bottom left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }
        return false;
      }
    };
  };
  BRp$2.registerNodeShapes = function () {
    var nodeShapes = this.nodeShapes = {};
    var renderer = this;
    this.generateEllipse();
    this.generatePolygon('triangle', generateUnitNgonPointsFitToSquare(3, 0));
    this.generateRoundPolygon('round-triangle', generateUnitNgonPointsFitToSquare(3, 0));
    this.generatePolygon('rectangle', generateUnitNgonPointsFitToSquare(4, 0));
    nodeShapes['square'] = nodeShapes['rectangle'];
    this.generateRoundRectangle();
    this.generateCutRectangle();
    this.generateBarrel();
    this.generateBottomRoundrectangle();
    {
      var diamondPoints = [0, 1, 1, 0, 0, -1, -1, 0];
      this.generatePolygon('diamond', diamondPoints);
      this.generateRoundPolygon('round-diamond', diamondPoints);
    }
    this.generatePolygon('pentagon', generateUnitNgonPointsFitToSquare(5, 0));
    this.generateRoundPolygon('round-pentagon', generateUnitNgonPointsFitToSquare(5, 0));
    this.generatePolygon('hexagon', generateUnitNgonPointsFitToSquare(6, 0));
    this.generateRoundPolygon('round-hexagon', generateUnitNgonPointsFitToSquare(6, 0));
    this.generatePolygon('heptagon', generateUnitNgonPointsFitToSquare(7, 0));
    this.generateRoundPolygon('round-heptagon', generateUnitNgonPointsFitToSquare(7, 0));
    this.generatePolygon('octagon', generateUnitNgonPointsFitToSquare(8, 0));
    this.generateRoundPolygon('round-octagon', generateUnitNgonPointsFitToSquare(8, 0));
    var star5Points = new Array(20);
    {
      var outerPoints = generateUnitNgonPoints(5, 0);
      var innerPoints = generateUnitNgonPoints(5, Math.PI / 5);

      // Outer radius is 1; inner radius of star is smaller
      var innerRadius = 0.5 * (3 - Math.sqrt(5));
      innerRadius *= 1.57;
      for (var i = 0; i < innerPoints.length / 2; i++) {
        innerPoints[i * 2] *= innerRadius;
        innerPoints[i * 2 + 1] *= innerRadius;
      }
      for (var i = 0; i < 20 / 4; i++) {
        star5Points[i * 4] = outerPoints[i * 2];
        star5Points[i * 4 + 1] = outerPoints[i * 2 + 1];
        star5Points[i * 4 + 2] = innerPoints[i * 2];
        star5Points[i * 4 + 3] = innerPoints[i * 2 + 1];
      }
    }
    star5Points = fitPolygonToSquare(star5Points);
    this.generatePolygon('star', star5Points);
    this.generatePolygon('vee', [-1, -1, 0, -0.333, 1, -1, 0, 1]);
    this.generatePolygon('rhomboid', [-1, -1, 0.333, -1, 1, 1, -0.333, 1]);
    this.generatePolygon('right-rhomboid', [-0.333, -1, 1, -1, 0.333, 1, -1, 1]);
    this.nodeShapes['concavehexagon'] = this.generatePolygon('concave-hexagon', [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]);
    {
      var tagPoints = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1];
      this.generatePolygon('tag', tagPoints);
      this.generateRoundPolygon('round-tag', tagPoints);
    }
    nodeShapes.makePolygon = function (points) {
      // use caching on user-specified polygons so they are as fast as native shapes

      var key = points.join('$');
      var name = 'polygon-' + key;
      var shape;
      if (shape = this[name]) {
        // got cached shape
        return shape;
      }

      // create and cache new shape
      return renderer.generatePolygon(name, points);
    };
  };

  var BRp$1 = {};
  BRp$1.timeToRender = function () {
    return this.redrawTotalTime / this.redrawCount;
  };
  BRp$1.redraw = function (options) {
    options = options || staticEmptyObject();
    var r = this;
    if (r.averageRedrawTime === undefined) {
      r.averageRedrawTime = 0;
    }
    if (r.lastRedrawTime === undefined) {
      r.lastRedrawTime = 0;
    }
    if (r.lastDrawTime === undefined) {
      r.lastDrawTime = 0;
    }
    r.requestedFrame = true;
    r.renderOptions = options;
  };
  BRp$1.beforeRender = function (fn, priority) {
    // the renderer can't add tick callbacks when destroyed
    if (this.destroyed) {
      return;
    }
    if (priority == null) {
      error('Priority is not optional for beforeRender');
    }
    var cbs = this.beforeRenderCallbacks;
    cbs.push({
      fn: fn,
      priority: priority
    });

    // higher priority callbacks executed first
    cbs.sort(function (a, b) {
      return b.priority - a.priority;
    });
  };
  var beforeRenderCallbacks = function beforeRenderCallbacks(r, willDraw, startTime) {
    var cbs = r.beforeRenderCallbacks;
    for (var i = 0; i < cbs.length; i++) {
      cbs[i].fn(willDraw, startTime);
    }
  };
  BRp$1.startRenderLoop = function () {
    var r = this;
    var cy = r.cy;
    if (r.renderLoopStarted) {
      return;
    } else {
      r.renderLoopStarted = true;
    }
    var renderFn = function renderFn(requestTime) {
      if (r.destroyed) {
        return;
      }
      if (cy.batching()) ; else if (r.requestedFrame && !r.skipFrame) {
        beforeRenderCallbacks(r, true, requestTime);
        var startTime = performanceNow();
        r.render(r.renderOptions);
        var endTime = r.lastDrawTime = performanceNow();
        if (r.averageRedrawTime === undefined) {
          r.averageRedrawTime = endTime - startTime;
        }
        if (r.redrawCount === undefined) {
          r.redrawCount = 0;
        }
        r.redrawCount++;
        if (r.redrawTotalTime === undefined) {
          r.redrawTotalTime = 0;
        }
        var duration = endTime - startTime;
        r.redrawTotalTime += duration;
        r.lastRedrawTime = duration;

        // use a weighted average with a bias from the previous average so we don't spike so easily
        r.averageRedrawTime = r.averageRedrawTime / 2 + duration / 2;
        r.requestedFrame = false;
      } else {
        beforeRenderCallbacks(r, false, requestTime);
      }
      r.skipFrame = false;
      requestAnimationFrame(renderFn);
    };
    requestAnimationFrame(renderFn);
  };

  var BaseRenderer = function BaseRenderer(options) {
    this.init(options);
  };
  var BR = BaseRenderer;
  var BRp = BR.prototype;
  BRp.clientFunctions = ['redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl'];
  BRp.init = function (options) {
    var r = this;
    r.options = options;
    r.cy = options.cy;
    var ctr = r.container = options.cy.container();
    var containerWindow = r.cy.window();

    // prepend a stylesheet in the head such that
    if (containerWindow) {
      var document = containerWindow.document;
      var head = document.head;
      var stylesheetId = '__________cytoscape_stylesheet';
      var className = '__________cytoscape_container';
      var stylesheetAlreadyExists = document.getElementById(stylesheetId) != null;
      if (ctr.className.indexOf(className) < 0) {
        ctr.className = (ctr.className || '') + ' ' + className;
      }
      if (!stylesheetAlreadyExists) {
        var stylesheet = document.createElement('style');
        stylesheet.id = stylesheetId;
        stylesheet.textContent = '.' + className + ' { position: relative; }';
        head.insertBefore(stylesheet, head.children[0]); // first so lowest priority
      }

      var computedStyle = containerWindow.getComputedStyle(ctr);
      var position = computedStyle.getPropertyValue('position');
      if (position === 'static') {
        warn('A Cytoscape container has style position:static and so can not use UI extensions properly');
      }
    }
    r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag

    r.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95];

    //--Pointer-related data
    r.hoverData = {
      down: null,
      last: null,
      downTime: null,
      triggerMode: null,
      dragging: false,
      initialPan: [null, null],
      capture: false
    };
    r.dragData = {
      possibleDragElements: []
    };
    r.touchData = {
      start: null,
      capture: false,
      // These 3 fields related to tap, taphold events
      startPosition: [null, null, null, null, null, null],
      singleTouchStartTime: null,
      singleTouchMoved: true,
      now: [null, null, null, null, null, null],
      earlier: [null, null, null, null, null, null]
    };
    r.redraws = 0;
    r.showFps = options.showFps;
    r.debug = options.debug;
    r.hideEdgesOnViewport = options.hideEdgesOnViewport;
    r.textureOnViewport = options.textureOnViewport;
    r.wheelSensitivity = options.wheelSensitivity;
    r.motionBlurEnabled = options.motionBlur; // on by default
    r.forcedPixelRatio = number$1(options.pixelRatio) ? options.pixelRatio : null;
    r.motionBlur = options.motionBlur; // for initial kick off
    r.motionBlurOpacity = options.motionBlurOpacity;
    r.motionBlurTransparency = 1 - r.motionBlurOpacity;
    r.motionBlurPxRatio = 1;
    r.mbPxRBlurry = 1; //0.8;
    r.minMbLowQualFrames = 4;
    r.fullQualityMb = false;
    r.clearedForMotionBlur = [];
    r.desktopTapThreshold = options.desktopTapThreshold;
    r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold;
    r.touchTapThreshold = options.touchTapThreshold;
    r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold;
    r.tapholdDuration = 500;
    r.bindings = [];
    r.beforeRenderCallbacks = [];
    r.beforeRenderPriorities = {
      // higher priority execs before lower one
      animations: 400,
      eleCalcs: 300,
      eleTxrDeq: 200,
      lyrTxrDeq: 150,
      lyrTxrSkip: 100
    };
    r.registerNodeShapes();
    r.registerArrowShapes();
    r.registerCalculationListeners();
  };
  BRp.notify = function (eventName, eles) {
    var r = this;
    var cy = r.cy;

    // the renderer can't be notified after it's destroyed
    if (this.destroyed) {
      return;
    }
    if (eventName === 'init') {
      r.load();
      return;
    }
    if (eventName === 'destroy') {
      r.destroy();
      return;
    }
    if (eventName === 'add' || eventName === 'remove' || eventName === 'move' && cy.hasCompoundNodes() || eventName === 'load' || eventName === 'zorder' || eventName === 'mount') {
      r.invalidateCachedZSortedEles();
    }
    if (eventName === 'viewport') {
      r.redrawHint('select', true);
    }
    if (eventName === 'load' || eventName === 'resize' || eventName === 'mount') {
      r.invalidateContainerClientCoordsCache();
      r.matchCanvasSize(r.container);
    }
    r.redrawHint('eles', true);
    r.redrawHint('drag', true);
    this.startRenderLoop();
    this.redraw();
  };
  BRp.destroy = function () {
    var r = this;
    r.destroyed = true;
    r.cy.stopAnimationLoop();
    for (var i = 0; i < r.bindings.length; i++) {
      var binding = r.bindings[i];
      var b = binding;
      var tgt = b.target;
      (tgt.off || tgt.removeEventListener).apply(tgt, b.args);
    }
    r.bindings = [];
    r.beforeRenderCallbacks = [];
    r.onUpdateEleCalcsFns = [];
    if (r.removeObserver) {
      r.removeObserver.disconnect();
    }
    if (r.styleObserver) {
      r.styleObserver.disconnect();
    }
    if (r.resizeObserver) {
      r.resizeObserver.disconnect();
    }
    if (r.labelCalcDiv) {
      try {
        document.body.removeChild(r.labelCalcDiv); // eslint-disable-line no-undef
      } catch (e) {
        // ie10 issue #1014
      }
    }
  };
  BRp.isHeadless = function () {
    return false;
  };
  [BRp$f, BRp$5, BRp$4, BRp$3, BRp$2, BRp$1].forEach(function (props) {
    extend(BRp, props);
  });

  var fullFpsTime = 1000 / 60; // assume 60 frames per second

  var defs = {
    setupDequeueing: function setupDequeueing(opts) {
      return function setupDequeueingImpl() {
        var self = this;
        var r = this.renderer;
        if (self.dequeueingSetup) {
          return;
        } else {
          self.dequeueingSetup = true;
        }
        var queueRedraw = debounce_1(function () {
          r.redrawHint('eles', true);
          r.redrawHint('drag', true);
          r.redraw();
        }, opts.deqRedrawThreshold);
        var dequeue = function dequeue(willDraw, frameStartTime) {
          var startTime = performanceNow();
          var avgRenderTime = r.averageRedrawTime;
          var renderTime = r.lastRedrawTime;
          var deqd = [];
          var extent = r.cy.extent();
          var pixelRatio = r.getPixelRatio();

          // if we aren't in a tick that causes a draw, then the rendered style
          // queue won't automatically be flushed before dequeueing starts
          if (!willDraw) {
            r.flushRenderedStyleQueue();
          }
          while (true) {
            // eslint-disable-line no-constant-condition
            var now = performanceNow();
            var duration = now - startTime;
            var frameDuration = now - frameStartTime;
            if (renderTime < fullFpsTime) {
              // if we're rendering faster than the ideal fps, then do dequeueing
              // during all of the remaining frame time

              var timeAvailable = fullFpsTime - (willDraw ? avgRenderTime : 0);
              if (frameDuration >= opts.deqFastCost * timeAvailable) {
                break;
              }
            } else {
              if (willDraw) {
                if (duration >= opts.deqCost * renderTime || duration >= opts.deqAvgCost * avgRenderTime) {
                  break;
                }
              } else if (frameDuration >= opts.deqNoDrawCost * fullFpsTime) {
                break;
              }
            }
            var thisDeqd = opts.deq(self, pixelRatio, extent);
            if (thisDeqd.length > 0) {
              for (var i = 0; i < thisDeqd.length; i++) {
                deqd.push(thisDeqd[i]);
              }
            } else {
              break;
            }
          }

          // callbacks on dequeue
          if (deqd.length > 0) {
            opts.onDeqd(self, deqd);
            if (!willDraw && opts.shouldRedraw(self, deqd, pixelRatio, extent)) {
              queueRedraw();
            }
          }
        };
        var priority = opts.priority || noop$1;
        r.beforeRender(dequeue, priority(self));
      };
    }
  };

  // Allows lookups for (ele, lvl) => cache.
  // Uses keys so elements may share the same cache.
  var ElementTextureCacheLookup = /*#__PURE__*/function () {
    function ElementTextureCacheLookup(getKey) {
      var doesEleInvalidateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : falsify;
      _classCallCheck(this, ElementTextureCacheLookup);
      this.idsByKey = new Map$2();
      this.keyForId = new Map$2();
      this.cachesByLvl = new Map$2();
      this.lvls = [];
      this.getKey = getKey;
      this.doesEleInvalidateKey = doesEleInvalidateKey;
    }
    _createClass(ElementTextureCacheLookup, [{
      key: "getIdsFor",
      value: function getIdsFor(key) {
        if (key == null) {
          error("Can not get id list for null key");
        }
        var idsByKey = this.idsByKey;
        var ids = this.idsByKey.get(key);
        if (!ids) {
          ids = new Set$1();
          idsByKey.set(key, ids);
        }
        return ids;
      }
    }, {
      key: "addIdForKey",
      value: function addIdForKey(key, id) {
        if (key != null) {
          this.getIdsFor(key).add(id);
        }
      }
    }, {
      key: "deleteIdForKey",
      value: function deleteIdForKey(key, id) {
        if (key != null) {
          this.getIdsFor(key)["delete"](id);
        }
      }
    }, {
      key: "getNumberOfIdsForKey",
      value: function getNumberOfIdsForKey(key) {
        if (key == null) {
          return 0;
        } else {
          return this.getIdsFor(key).size;
        }
      }
    }, {
      key: "updateKeyMappingFor",
      value: function updateKeyMappingFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        var currKey = this.getKey(ele);
        this.deleteIdForKey(prevKey, id);
        this.addIdForKey(currKey, id);
        this.keyForId.set(id, currKey);
      }
    }, {
      key: "deleteKeyMappingFor",
      value: function deleteKeyMappingFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        this.deleteIdForKey(prevKey, id);
        this.keyForId["delete"](id);
      }
    }, {
      key: "keyHasChangedFor",
      value: function keyHasChangedFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        var newKey = this.getKey(ele);
        return prevKey !== newKey;
      }
    }, {
      key: "isInvalid",
      value: function isInvalid(ele) {
        return this.keyHasChangedFor(ele) || this.doesEleInvalidateKey(ele);
      }
    }, {
      key: "getCachesAt",
      value: function getCachesAt(lvl) {
        var cachesByLvl = this.cachesByLvl,
          lvls = this.lvls;
        var caches = cachesByLvl.get(lvl);
        if (!caches) {
          caches = new Map$2();
          cachesByLvl.set(lvl, caches);
          lvls.push(lvl);
        }
        return caches;
      }
    }, {
      key: "getCache",
      value: function getCache(key, lvl) {
        return this.getCachesAt(lvl).get(key);
      }
    }, {
      key: "get",
      value: function get(ele, lvl) {
        var key = this.getKey(ele);
        var cache = this.getCache(key, lvl);

        // getting for an element may need to add to the id list b/c eles can share keys
        if (cache != null) {
          this.updateKeyMappingFor(ele);
        }
        return cache;
      }
    }, {
      key: "getForCachedKey",
      value: function getForCachedKey(ele, lvl) {
        var key = this.keyForId.get(ele.id()); // n.b. use cached key, not newly computed key
        var cache = this.getCache(key, lvl);
        return cache;
      }
    }, {
      key: "hasCache",
      value: function hasCache(key, lvl) {
        return this.getCachesAt(lvl).has(key);
      }
    }, {
      key: "has",
      value: function has(ele, lvl) {
        var key = this.getKey(ele);
        return this.hasCache(key, lvl);
      }
    }, {
      key: "setCache",
      value: function setCache(key, lvl, cache) {
        cache.key = key;
        this.getCachesAt(lvl).set(key, cache);
      }
    }, {
      key: "set",
      value: function set(ele, lvl, cache) {
        var key = this.getKey(ele);
        this.setCache(key, lvl, cache);
        this.updateKeyMappingFor(ele);
      }
    }, {
      key: "deleteCache",
      value: function deleteCache(key, lvl) {
        this.getCachesAt(lvl)["delete"](key);
      }
    }, {
      key: "delete",
      value: function _delete(ele, lvl) {
        var key = this.getKey(ele);
        this.deleteCache(key, lvl);
      }
    }, {
      key: "invalidateKey",
      value: function invalidateKey(key) {
        var _this = this;
        this.lvls.forEach(function (lvl) {
          return _this.deleteCache(key, lvl);
        });
      }

      // returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key)
    }, {
      key: "invalidate",
      value: function invalidate(ele) {
        var id = ele.id();
        var key = this.keyForId.get(id); // n.b. use stored key rather than current (potential key)

        this.deleteKeyMappingFor(ele);
        var entireKeyInvalidated = this.doesEleInvalidateKey(ele);
        if (entireKeyInvalidated) {
          // clear mapping for current key
          this.invalidateKey(key);
        }
        return entireKeyInvalidated || this.getNumberOfIdsForKey(key) === 0;
      }
    }]);
    return ElementTextureCacheLookup;
  }();

  var minTxrH = 25; // the size of the texture cache for small height eles (special case)
  var txrStepH = 50; // the min size of the regular cache, and the size it increases with each step up
  var minLvl$1 = -4; // when scaling smaller than that we don't need to re-render
  var maxLvl$1 = 3; // when larger than this scale just render directly (caching is not helpful)
  var maxZoom$1 = 7.99; // beyond this zoom level, layered textures are not used
  var eleTxrSpacing = 8; // spacing between elements on textures to avoid blitting overlaps
  var defTxrWidth = 1024; // default/minimum texture width
  var maxTxrW = 1024; // the maximum width of a texture
  var maxTxrH = 1024; // the maximum height of a texture
  var minUtility = 0.2; // if usage of texture is less than this, it is retired
  var maxFullness = 0.8; // fullness of texture after which queue removal is checked
  var maxFullnessChecks = 10; // dequeued after this many checks
  var deqCost$1 = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame
  var deqAvgCost$1 = 0.1; // % of add'l rendering cost compared to average overall redraw time
  var deqNoDrawCost$1 = 0.9; // % of avg frame time that can be used for dequeueing when not drawing
  var deqFastCost$1 = 0.9; // % of frame time to be used when >60fps
  var deqRedrawThreshold$1 = 100; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile
  var maxDeqSize$1 = 1; // number of eles to dequeue and render at higher texture in each batch

  var getTxrReasons = {
    dequeue: 'dequeue',
    downscale: 'downscale',
    highQuality: 'highQuality'
  };
  var initDefaults = defaults$g({
    getKey: null,
    doesEleInvalidateKey: falsify,
    drawElement: null,
    getBoundingBox: null,
    getRotationPoint: null,
    getRotationOffset: null,
    isVisible: trueify,
    allowEdgeTxrCaching: true,
    allowParentTxrCaching: true
  });
  var ElementTextureCache = function ElementTextureCache(renderer, initOptions) {
    var self = this;
    self.renderer = renderer;
    self.onDequeues = [];
    var opts = initDefaults(initOptions);
    extend(self, opts);
    self.lookup = new ElementTextureCacheLookup(opts.getKey, opts.doesEleInvalidateKey);
    self.setupDequeueing();
  };
  var ETCp = ElementTextureCache.prototype;
  ETCp.reasons = getTxrReasons;

  // the list of textures in which new subtextures for elements can be placed
  ETCp.getTextureQueue = function (txrH) {
    var self = this;
    self.eleImgCaches = self.eleImgCaches || {};
    return self.eleImgCaches[txrH] = self.eleImgCaches[txrH] || [];
  };

  // the list of usused textures which can be recycled (in use in texture queue)
  ETCp.getRetiredTextureQueue = function (txrH) {
    var self = this;
    var rtxtrQs = self.eleImgCaches.retired = self.eleImgCaches.retired || {};
    var rtxtrQ = rtxtrQs[txrH] = rtxtrQs[txrH] || [];
    return rtxtrQ;
  };

  // queue of element draw requests at different scale levels
  ETCp.getElementQueue = function () {
    var self = this;
    var q = self.eleCacheQueue = self.eleCacheQueue || new heap(function (a, b) {
      return b.reqs - a.reqs;
    });
    return q;
  };

  // queue of element draw requests at different scale levels (element id lookup)
  ETCp.getElementKeyToQueue = function () {
    var self = this;
    var k2q = self.eleKeyToCacheQueue = self.eleKeyToCacheQueue || {};
    return k2q;
  };
  ETCp.getElement = function (ele, bb, pxRatio, lvl, reason) {
    var self = this;
    var r = this.renderer;
    var zoom = r.cy.zoom();
    var lookup = this.lookup;
    if (!bb || bb.w === 0 || bb.h === 0 || isNaN(bb.w) || isNaN(bb.h) || !ele.visible() || ele.removed()) {
      return null;
    }
    if (!self.allowEdgeTxrCaching && ele.isEdge() || !self.allowParentTxrCaching && ele.isParent()) {
      return null;
    }
    if (lvl == null) {
      lvl = Math.ceil(log2(zoom * pxRatio));
    }
    if (lvl < minLvl$1) {
      lvl = minLvl$1;
    } else if (zoom >= maxZoom$1 || lvl > maxLvl$1) {
      return null;
    }
    var scale = Math.pow(2, lvl);
    var eleScaledH = bb.h * scale;
    var eleScaledW = bb.w * scale;
    var scaledLabelShown = r.eleTextBiggerThanMin(ele, scale);
    if (!this.isVisible(ele, scaledLabelShown)) {
      return null;
    }
    var eleCache = lookup.get(ele, lvl);

    // if this get was on an unused/invalidated cache, then restore the texture usage metric
    if (eleCache && eleCache.invalidated) {
      eleCache.invalidated = false;
      eleCache.texture.invalidatedWidth -= eleCache.width;
    }
    if (eleCache) {
      return eleCache;
    }
    var txrH; // which texture height this ele belongs to

    if (eleScaledH <= minTxrH) {
      txrH = minTxrH;
    } else if (eleScaledH <= txrStepH) {
      txrH = txrStepH;
    } else {
      txrH = Math.ceil(eleScaledH / txrStepH) * txrStepH;
    }
    if (eleScaledH > maxTxrH || eleScaledW > maxTxrW) {
      return null; // caching large elements is not efficient
    }

    var txrQ = self.getTextureQueue(txrH);

    // first try the second last one in case it has space at the end
    var txr = txrQ[txrQ.length - 2];
    var addNewTxr = function addNewTxr() {
      return self.recycleTexture(txrH, eleScaledW) || self.addTexture(txrH, eleScaledW);
    };

    // try the last one if there is no second last one
    if (!txr) {
      txr = txrQ[txrQ.length - 1];
    }

    // if the last one doesn't exist, we need a first one
    if (!txr) {
      txr = addNewTxr();
    }

    // if there's no room in the current texture, we need a new one
    if (txr.width - txr.usedWidth < eleScaledW) {
      txr = addNewTxr();
    }
    var scalableFrom = function scalableFrom(otherCache) {
      return otherCache && otherCache.scaledLabelShown === scaledLabelShown;
    };
    var deqing = reason && reason === getTxrReasons.dequeue;
    var highQualityReq = reason && reason === getTxrReasons.highQuality;
    var downscaleReq = reason && reason === getTxrReasons.downscale;
    var higherCache; // the nearest cache with a higher level
    for (var l = lvl + 1; l <= maxLvl$1; l++) {
      var c = lookup.get(ele, l);
      if (c) {
        higherCache = c;
        break;
      }
    }
    var oneUpCache = higherCache && higherCache.level === lvl + 1 ? higherCache : null;
    var downscale = function downscale() {
      txr.context.drawImage(oneUpCache.texture.canvas, oneUpCache.x, 0, oneUpCache.width, oneUpCache.height, txr.usedWidth, 0, eleScaledW, eleScaledH);
    };

    // reset ele area in texture
    txr.context.setTransform(1, 0, 0, 1, 0, 0);
    txr.context.clearRect(txr.usedWidth, 0, eleScaledW, txrH);
    if (scalableFrom(oneUpCache)) {
      // then we can relatively cheaply rescale the existing image w/o rerendering
      downscale();
    } else if (scalableFrom(higherCache)) {
      // then use the higher cache for now and queue the next level down
      // to cheaply scale towards the smaller level

      if (highQualityReq) {
        for (var _l = higherCache.level; _l > lvl; _l--) {
          oneUpCache = self.getElement(ele, bb, pxRatio, _l, getTxrReasons.downscale);
        }
        downscale();
      } else {
        self.queueElement(ele, higherCache.level - 1);
        return higherCache;
      }
    } else {
      var lowerCache; // the nearest cache with a lower level
      if (!deqing && !highQualityReq && !downscaleReq) {
        for (var _l2 = lvl - 1; _l2 >= minLvl$1; _l2--) {
          var _c = lookup.get(ele, _l2);
          if (_c) {
            lowerCache = _c;
            break;
          }
        }
      }
      if (scalableFrom(lowerCache)) {
        // then use the lower quality cache for now and queue the better one for later

        self.queueElement(ele, lvl);
        return lowerCache;
      }
      txr.context.translate(txr.usedWidth, 0);
      txr.context.scale(scale, scale);
      this.drawElement(txr.context, ele, bb, scaledLabelShown, false);
      txr.context.scale(1 / scale, 1 / scale);
      txr.context.translate(-txr.usedWidth, 0);
    }
    eleCache = {
      x: txr.usedWidth,
      texture: txr,
      level: lvl,
      scale: scale,
      width: eleScaledW,
      height: eleScaledH,
      scaledLabelShown: scaledLabelShown
    };
    txr.usedWidth += Math.ceil(eleScaledW + eleTxrSpacing);
    txr.eleCaches.push(eleCache);
    lookup.set(ele, lvl, eleCache);
    self.checkTextureFullness(txr);
    return eleCache;
  };
  ETCp.invalidateElements = function (eles) {
    for (var i = 0; i < eles.length; i++) {
      this.invalidateElement(eles[i]);
    }
  };
  ETCp.invalidateElement = function (ele) {
    var self = this;
    var lookup = self.lookup;
    var caches = [];
    var invalid = lookup.isInvalid(ele);
    if (!invalid) {
      return; // override the invalidation request if the element key has not changed
    }

    for (var lvl = minLvl$1; lvl <= maxLvl$1; lvl++) {
      var cache = lookup.getForCachedKey(ele, lvl);
      if (cache) {
        caches.push(cache);
      }
    }
    var noOtherElesUseCache = lookup.invalidate(ele);
    if (noOtherElesUseCache) {
      for (var i = 0; i < caches.length; i++) {
        var _cache = caches[i];
        var txr = _cache.texture;

        // remove space from the texture it belongs to
        txr.invalidatedWidth += _cache.width;

        // mark the cache as invalidated
        _cache.invalidated = true;

        // retire the texture if its utility is low
        self.checkTextureUtility(txr);
      }
    }

    // remove from queue since the old req was for the old state
    self.removeFromQueue(ele);
  };
  ETCp.checkTextureUtility = function (txr) {
    // invalidate all entries in the cache if the cache size is small
    if (txr.invalidatedWidth >= minUtility * txr.width) {
      this.retireTexture(txr);
    }
  };
  ETCp.checkTextureFullness = function (txr) {
    // if texture has been mostly filled and passed over several times, remove
    // it from the queue so we don't need to waste time looking at it to put new things

    var self = this;
    var txrQ = self.getTextureQueue(txr.height);
    if (txr.usedWidth / txr.width > maxFullness && txr.fullnessChecks >= maxFullnessChecks) {
      removeFromArray(txrQ, txr);
    } else {
      txr.fullnessChecks++;
    }
  };
  ETCp.retireTexture = function (txr) {
    var self = this;
    var txrH = txr.height;
    var txrQ = self.getTextureQueue(txrH);
    var lookup = this.lookup;

    // retire the texture from the active / searchable queue:

    removeFromArray(txrQ, txr);
    txr.retired = true;

    // remove the refs from the eles to the caches:

    var eleCaches = txr.eleCaches;
    for (var i = 0; i < eleCaches.length; i++) {
      var eleCache = eleCaches[i];
      lookup.deleteCache(eleCache.key, eleCache.level);
    }
    clearArray(eleCaches);

    // add the texture to a retired queue so it can be recycled in future:

    var rtxtrQ = self.getRetiredTextureQueue(txrH);
    rtxtrQ.push(txr);
  };
  ETCp.addTexture = function (txrH, minW) {
    var self = this;
    var txrQ = self.getTextureQueue(txrH);
    var txr = {};
    txrQ.push(txr);
    txr.eleCaches = [];
    txr.height = txrH;
    txr.width = Math.max(defTxrWidth, minW);
    txr.usedWidth = 0;
    txr.invalidatedWidth = 0;
    txr.fullnessChecks = 0;
    txr.canvas = self.renderer.makeOffscreenCanvas(txr.width, txr.height);
    txr.context = txr.canvas.getContext('2d');
    return txr;
  };
  ETCp.recycleTexture = function (txrH, minW) {
    var self = this;
    var txrQ = self.getTextureQueue(txrH);
    var rtxtrQ = self.getRetiredTextureQueue(txrH);
    for (var i = 0; i < rtxtrQ.length; i++) {
      var txr = rtxtrQ[i];
      if (txr.width >= minW) {
        txr.retired = false;
        txr.usedWidth = 0;
        txr.invalidatedWidth = 0;
        txr.fullnessChecks = 0;
        clearArray(txr.eleCaches);
        txr.context.setTransform(1, 0, 0, 1, 0, 0);
        txr.context.clearRect(0, 0, txr.width, txr.height);
        removeFromArray(rtxtrQ, txr);
        txrQ.push(txr);
        return txr;
      }
    }
  };
  ETCp.queueElement = function (ele, lvl) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var key = this.getKey(ele);
    var existingReq = k2q[key];
    if (existingReq) {
      // use the max lvl b/c in between lvls are cheap to make
      existingReq.level = Math.max(existingReq.level, lvl);
      existingReq.eles.merge(ele);
      existingReq.reqs++;
      q.updateItem(existingReq);
    } else {
      var req = {
        eles: ele.spawn().merge(ele),
        level: lvl,
        reqs: 1,
        key: key
      };
      q.push(req);
      k2q[key] = req;
    }
  };
  ETCp.dequeue = function (pxRatio /*, extent*/) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var dequeued = [];
    var lookup = self.lookup;
    for (var i = 0; i < maxDeqSize$1; i++) {
      if (q.size() > 0) {
        var req = q.pop();
        var key = req.key;
        var ele = req.eles[0]; // all eles have the same key
        var cacheExists = lookup.hasCache(ele, req.level);

        // clear out the key to req lookup
        k2q[key] = null;

        // dequeueing isn't necessary with an existing cache
        if (cacheExists) {
          continue;
        }
        dequeued.push(req);
        var bb = self.getBoundingBox(ele);
        self.getElement(ele, bb, pxRatio, req.level, getTxrReasons.dequeue);
      } else {
        break;
      }
    }
    return dequeued;
  };
  ETCp.removeFromQueue = function (ele) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var key = this.getKey(ele);
    var req = k2q[key];
    if (req != null) {
      if (req.eles.length === 1) {
        // remove if last ele in the req
        // bring to front of queue
        req.reqs = MAX_INT$1;
        q.updateItem(req);
        q.pop(); // remove from queue

        k2q[key] = null; // remove from lookup map
      } else {
        // otherwise just remove ele from req
        req.eles.unmerge(ele);
      }
    }
  };
  ETCp.onDequeue = function (fn) {
    this.onDequeues.push(fn);
  };
  ETCp.offDequeue = function (fn) {
    removeFromArray(this.onDequeues, fn);
  };
  ETCp.setupDequeueing = defs.setupDequeueing({
    deqRedrawThreshold: deqRedrawThreshold$1,
    deqCost: deqCost$1,
    deqAvgCost: deqAvgCost$1,
    deqNoDrawCost: deqNoDrawCost$1,
    deqFastCost: deqFastCost$1,
    deq: function deq(self, pxRatio, extent) {
      return self.dequeue(pxRatio, extent);
    },
    onDeqd: function onDeqd(self, deqd) {
      for (var i = 0; i < self.onDequeues.length; i++) {
        var fn = self.onDequeues[i];
        fn(deqd);
      }
    },
    shouldRedraw: function shouldRedraw(self, deqd, pxRatio, extent) {
      for (var i = 0; i < deqd.length; i++) {
        var eles = deqd[i].eles;
        for (var j = 0; j < eles.length; j++) {
          var bb = eles[j].boundingBox();
          if (boundingBoxesIntersect(bb, extent)) {
            return true;
          }
        }
      }
      return false;
    },
    priority: function priority(self) {
      return self.renderer.beforeRenderPriorities.eleTxrDeq;
    }
  });

  var defNumLayers = 1; // default number of layers to use
  var minLvl = -4; // when scaling smaller than that we don't need to re-render
  var maxLvl = 2; // when larger than this scale just render directly (caching is not helpful)
  var maxZoom = 3.99; // beyond this zoom level, layered textures are not used
  var deqRedrawThreshold = 50; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile
  var refineEleDebounceTime = 50; // time to debounce sharper ele texture updates
  var deqCost = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame
  var deqAvgCost = 0.1; // % of add'l rendering cost compared to average overall redraw time
  var deqNoDrawCost = 0.9; // % of avg frame time that can be used for dequeueing when not drawing
  var deqFastCost = 0.9; // % of frame time to be used when >60fps
  var maxDeqSize = 1; // number of eles to dequeue and render at higher texture in each batch
  var invalidThreshold = 250; // time threshold for disabling b/c of invalidations
  var maxLayerArea = 4000 * 4000; // layers can't be bigger than this
  var useHighQualityEleTxrReqs = true; // whether to use high quality ele txr requests (generally faster and cheaper in the longterm)

  // var log = function(){ console.log.apply( console, arguments ); };

  var LayeredTextureCache = function LayeredTextureCache(renderer) {
    var self = this;
    var r = self.renderer = renderer;
    var cy = r.cy;
    self.layersByLevel = {}; // e.g. 2 => [ layer1, layer2, ..., layerN ]

    self.firstGet = true;
    self.lastInvalidationTime = performanceNow() - 2 * invalidThreshold;
    self.skipping = false;
    self.eleTxrDeqs = cy.collection();
    self.scheduleElementRefinement = debounce_1(function () {
      self.refineElementTextures(self.eleTxrDeqs);
      self.eleTxrDeqs.unmerge(self.eleTxrDeqs);
    }, refineEleDebounceTime);
    r.beforeRender(function (willDraw, now) {
      if (now - self.lastInvalidationTime <= invalidThreshold) {
        self.skipping = true;
      } else {
        self.skipping = false;
      }
    }, r.beforeRenderPriorities.lyrTxrSkip);
    var qSort = function qSort(a, b) {
      return b.reqs - a.reqs;
    };
    self.layersQueue = new heap(qSort);
    self.setupDequeueing();
  };
  var LTCp = LayeredTextureCache.prototype;
  var layerIdPool = 0;
  var MAX_INT = Math.pow(2, 53) - 1;
  LTCp.makeLayer = function (bb, lvl) {
    var scale = Math.pow(2, lvl);
    var w = Math.ceil(bb.w * scale);
    var h = Math.ceil(bb.h * scale);
    var canvas = this.renderer.makeOffscreenCanvas(w, h);
    var layer = {
      id: layerIdPool = ++layerIdPool % MAX_INT,
      bb: bb,
      level: lvl,
      width: w,
      height: h,
      canvas: canvas,
      context: canvas.getContext('2d'),
      eles: [],
      elesQueue: [],
      reqs: 0
    };

    // log('make layer %s with w %s and h %s and lvl %s', layer.id, layer.width, layer.height, layer.level);

    var cxt = layer.context;
    var dx = -layer.bb.x1;
    var dy = -layer.bb.y1;

    // do the transform on creation to save cycles (it's the same for all eles)
    cxt.scale(scale, scale);
    cxt.translate(dx, dy);
    return layer;
  };
  LTCp.getLayers = function (eles, pxRatio, lvl) {
    var self = this;
    var r = self.renderer;
    var cy = r.cy;
    var zoom = cy.zoom();
    var firstGet = self.firstGet;
    self.firstGet = false;

    // log('--\nget layers with %s eles', eles.length);
    //log eles.map(function(ele){ return ele.id() }) );

    if (lvl == null) {
      lvl = Math.ceil(log2(zoom * pxRatio));
      if (lvl < minLvl) {
        lvl = minLvl;
      } else if (zoom >= maxZoom || lvl > maxLvl) {
        return null;
      }
    }
    self.validateLayersElesOrdering(lvl, eles);
    var layersByLvl = self.layersByLevel;
    var scale = Math.pow(2, lvl);
    var layers = layersByLvl[lvl] = layersByLvl[lvl] || [];
    var bb;
    var lvlComplete = self.levelIsComplete(lvl, eles);
    var tmpLayers;
    var checkTempLevels = function checkTempLevels() {
      var canUseAsTmpLvl = function canUseAsTmpLvl(l) {
        self.validateLayersElesOrdering(l, eles);
        if (self.levelIsComplete(l, eles)) {
          tmpLayers = layersByLvl[l];
          return true;
        }
      };
      var checkLvls = function checkLvls(dir) {
        if (tmpLayers) {
          return;
        }
        for (var l = lvl + dir; minLvl <= l && l <= maxLvl; l += dir) {
          if (canUseAsTmpLvl(l)) {
            break;
          }
        }
      };
      checkLvls(+1);
      checkLvls(-1);

      // remove the invalid layers; they will be replaced as needed later in this function
      for (var i = layers.length - 1; i >= 0; i--) {
        var layer = layers[i];
        if (layer.invalid) {
          removeFromArray(layers, layer);
        }
      }
    };
    if (!lvlComplete) {
      // if the current level is incomplete, then use the closest, best quality layerset temporarily
      // and later queue the current layerset so we can get the proper quality level soon

      checkTempLevels();
    } else {
      // log('level complete, using existing layers\n--');
      return layers;
    }
    var getBb = function getBb() {
      if (!bb) {
        bb = makeBoundingBox();
        for (var i = 0; i < eles.length; i++) {
          updateBoundingBox(bb, eles[i].boundingBox());
        }
      }
      return bb;
    };
    var makeLayer = function makeLayer(opts) {
      opts = opts || {};
      var after = opts.after;
      getBb();
      var area = bb.w * scale * (bb.h * scale);
      if (area > maxLayerArea) {
        return null;
      }
      var layer = self.makeLayer(bb, lvl);
      if (after != null) {
        var index = layers.indexOf(after) + 1;
        layers.splice(index, 0, layer);
      } else if (opts.insert === undefined || opts.insert) {
        // no after specified => first layer made so put at start
        layers.unshift(layer);
      }

      // if( tmpLayers ){
      //self.queueLayer( layer );
      // }

      return layer;
    };
    if (self.skipping && !firstGet) {
      // log('skip layers');
      return null;
    }

    // log('do layers');

    var layer = null;
    var maxElesPerLayer = eles.length / defNumLayers;
    var allowLazyQueueing = !firstGet;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var rs = ele._private.rscratch;
      var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};

      // log('look at ele', ele.id());

      var existingLayer = caches[lvl];
      if (existingLayer) {
        // reuse layer for later eles
        // log('reuse layer for', ele.id());
        layer = existingLayer;
        continue;
      }
      if (!layer || layer.eles.length >= maxElesPerLayer || !boundingBoxInBoundingBox(layer.bb, ele.boundingBox())) {
        // log('make new layer for ele %s', ele.id());

        layer = makeLayer({
          insert: true,
          after: layer
        });

        // if now layer can be built then we can't use layers at this level
        if (!layer) {
          return null;
        }

        // log('new layer with id %s', layer.id);
      }

      if (tmpLayers || allowLazyQueueing) {
        // log('queue ele %s in layer %s', ele.id(), layer.id);
        self.queueLayer(layer, ele);
      } else {
        // log('draw ele %s in layer %s', ele.id(), layer.id);
        self.drawEleInLayer(layer, ele, lvl, pxRatio);
      }
      layer.eles.push(ele);
      caches[lvl] = layer;
    }

    // log('--');

    if (tmpLayers) {
      // then we only queued the current layerset and can't draw it yet
      return tmpLayers;
    }
    if (allowLazyQueueing) {
      // log('lazy queue level', lvl);
      return null;
    }
    return layers;
  };

  // a layer may want to use an ele cache of a higher level to avoid blurriness
  // so the layer level might not equal the ele level
  LTCp.getEleLevelForLayerLevel = function (lvl, pxRatio) {
    return lvl;
  };
  LTCp.drawEleInLayer = function (layer, ele, lvl, pxRatio) {
    var self = this;
    var r = this.renderer;
    var context = layer.context;
    var bb = ele.boundingBox();
    if (bb.w === 0 || bb.h === 0 || !ele.visible()) {
      return;
    }
    lvl = self.getEleLevelForLayerLevel(lvl, pxRatio);
    {
      r.setImgSmoothing(context, false);
    }
    {
      r.drawCachedElement(context, ele, null, null, lvl, useHighQualityEleTxrReqs);
    }
    {
      r.setImgSmoothing(context, true);
    }
  };
  LTCp.levelIsComplete = function (lvl, eles) {
    var self = this;
    var layers = self.layersByLevel[lvl];
    if (!layers || layers.length === 0) {
      return false;
    }
    var numElesInLayers = 0;
    for (var i = 0; i < layers.length; i++) {
      var layer = layers[i];

      // if there are any eles needed to be drawn yet, the level is not complete
      if (layer.reqs > 0) {
        return false;
      }

      // if the layer is invalid, the level is not complete
      if (layer.invalid) {
        return false;
      }
      numElesInLayers += layer.eles.length;
    }

    // we should have exactly the number of eles passed in to be complete
    if (numElesInLayers !== eles.length) {
      return false;
    }
    return true;
  };
  LTCp.validateLayersElesOrdering = function (lvl, eles) {
    var layers = this.layersByLevel[lvl];
    if (!layers) {
      return;
    }

    // if in a layer the eles are not in the same order, then the layer is invalid
    // (i.e. there is an ele in between the eles in the layer)

    for (var i = 0; i < layers.length; i++) {
      var layer = layers[i];
      var offset = -1;

      // find the offset
      for (var j = 0; j < eles.length; j++) {
        if (layer.eles[0] === eles[j]) {
          offset = j;
          break;
        }
      }
      if (offset < 0) {
        // then the layer has nonexistent elements and is invalid
        this.invalidateLayer(layer);
        continue;
      }

      // the eles in the layer must be in the same continuous order, else the layer is invalid

      var o = offset;
      for (var j = 0; j < layer.eles.length; j++) {
        if (layer.eles[j] !== eles[o + j]) {
          // log('invalidate based on ordering', layer.id);

          this.invalidateLayer(layer);
          break;
        }
      }
    }
  };
  LTCp.updateElementsInLayers = function (eles, update) {
    var self = this;
    var isEles = element(eles[0]);

    // collect udpated elements (cascaded from the layers) and update each
    // layer itself along the way
    for (var i = 0; i < eles.length; i++) {
      var req = isEles ? null : eles[i];
      var ele = isEles ? eles[i] : eles[i].ele;
      var rs = ele._private.rscratch;
      var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};
      for (var l = minLvl; l <= maxLvl; l++) {
        var layer = caches[l];
        if (!layer) {
          continue;
        }

        // if update is a request from the ele cache, then it affects only
        // the matching level
        if (req && self.getEleLevelForLayerLevel(layer.level) !== req.level) {
          continue;
        }
        update(layer, ele, req);
      }
    }
  };
  LTCp.haveLayers = function () {
    var self = this;
    var haveLayers = false;
    for (var l = minLvl; l <= maxLvl; l++) {
      var layers = self.layersByLevel[l];
      if (layers && layers.length > 0) {
        haveLayers = true;
        break;
      }
    }
    return haveLayers;
  };
  LTCp.invalidateElements = function (eles) {
    var self = this;
    if (eles.length === 0) {
      return;
    }
    self.lastInvalidationTime = performanceNow();

    // log('update invalidate layer time from eles');

    if (eles.length === 0 || !self.haveLayers()) {
      return;
    }
    self.updateElementsInLayers(eles, function invalAssocLayers(layer, ele, req) {
      self.invalidateLayer(layer);
    });
  };
  LTCp.invalidateLayer = function (layer) {
    // log('update invalidate layer time');

    this.lastInvalidationTime = performanceNow();
    if (layer.invalid) {
      return;
    } // save cycles

    var lvl = layer.level;
    var eles = layer.eles;
    var layers = this.layersByLevel[lvl];

    // log('invalidate layer', layer.id );

    removeFromArray(layers, layer);
    // layer.eles = [];

    layer.elesQueue = [];
    layer.invalid = true;
    if (layer.replacement) {
      layer.replacement.invalid = true;
    }
    for (var i = 0; i < eles.length; i++) {
      var caches = eles[i]._private.rscratch.imgLayerCaches;
      if (caches) {
        caches[lvl] = null;
      }
    }
  };
  LTCp.refineElementTextures = function (eles) {
    var self = this;

    // log('refine', eles.length);

    self.updateElementsInLayers(eles, function refineEachEle(layer, ele, req) {
      var rLyr = layer.replacement;
      if (!rLyr) {
        rLyr = layer.replacement = self.makeLayer(layer.bb, layer.level);
        rLyr.replaces = layer;
        rLyr.eles = layer.eles;

        // log('make replacement layer %s for %s with level %s', rLyr.id, layer.id, rLyr.level);
      }

      if (!rLyr.reqs) {
        for (var i = 0; i < rLyr.eles.length; i++) {
          self.queueLayer(rLyr, rLyr.eles[i]);
        }

        // log('queue replacement layer refinement', rLyr.id);
      }
    });
  };

  LTCp.enqueueElementRefinement = function (ele) {
    this.eleTxrDeqs.merge(ele);
    this.scheduleElementRefinement();
  };
  LTCp.queueLayer = function (layer, ele) {
    var self = this;
    var q = self.layersQueue;
    var elesQ = layer.elesQueue;
    var hasId = elesQ.hasId = elesQ.hasId || {};

    // if a layer is going to be replaced, queuing is a waste of time
    if (layer.replacement) {
      return;
    }
    if (ele) {
      if (hasId[ele.id()]) {
        return;
      }
      elesQ.push(ele);
      hasId[ele.id()] = true;
    }
    if (layer.reqs) {
      layer.reqs++;
      q.updateItem(layer);
    } else {
      layer.reqs = 1;
      q.push(layer);
    }
  };
  LTCp.dequeue = function (pxRatio) {
    var self = this;
    var q = self.layersQueue;
    var deqd = [];
    var eleDeqs = 0;
    while (eleDeqs < maxDeqSize) {
      if (q.size() === 0) {
        break;
      }
      var layer = q.peek();

      // if a layer has been or will be replaced, then don't waste time with it
      if (layer.replacement) {
        // log('layer %s in queue skipped b/c it already has a replacement', layer.id);
        q.pop();
        continue;
      }

      // if this is a replacement layer that has been superceded, then forget it
      if (layer.replaces && layer !== layer.replaces.replacement) {
        // log('layer is no longer the most uptodate replacement; dequeued', layer.id)
        q.pop();
        continue;
      }
      if (layer.invalid) {
        // log('replacement layer %s is invalid; dequeued', layer.id);
        q.pop();
        continue;
      }
      var ele = layer.elesQueue.shift();
      if (ele) {
        // log('dequeue layer %s', layer.id);

        self.drawEleInLayer(layer, ele, layer.level, pxRatio);
        eleDeqs++;
      }
      if (deqd.length === 0) {
        // we need only one entry in deqd to queue redrawing etc
        deqd.push(true);
      }

      // if the layer has all its eles done, then remove from the queue
      if (layer.elesQueue.length === 0) {
        q.pop();
        layer.reqs = 0;

        // log('dequeue of layer %s complete', layer.id);

        // when a replacement layer is dequeued, it replaces the old layer in the level
        if (layer.replaces) {
          self.applyLayerReplacement(layer);
        }
        self.requestRedraw();
      }
    }
    return deqd;
  };
  LTCp.applyLayerReplacement = function (layer) {
    var self = this;
    var layersInLevel = self.layersByLevel[layer.level];
    var replaced = layer.replaces;
    var index = layersInLevel.indexOf(replaced);

    // if the replaced layer is not in the active list for the level, then replacing
    // refs would be a mistake (i.e. overwriting the true active layer)
    if (index < 0 || replaced.invalid) {
      // log('replacement layer would have no effect', layer.id);
      return;
    }
    layersInLevel[index] = layer; // replace level ref

    // replace refs in eles
    for (var i = 0; i < layer.eles.length; i++) {
      var _p = layer.eles[i]._private;
      var cache = _p.imgLayerCaches = _p.imgLayerCaches || {};
      if (cache) {
        cache[layer.level] = layer;
      }
    }

    // log('apply replacement layer %s over %s', layer.id, replaced.id);

    self.requestRedraw();
  };
  LTCp.requestRedraw = debounce_1(function () {
    var r = this.renderer;
    r.redrawHint('eles', true);
    r.redrawHint('drag', true);
    r.redraw();
  }, 100);
  LTCp.setupDequeueing = defs.setupDequeueing({
    deqRedrawThreshold: deqRedrawThreshold,
    deqCost: deqCost,
    deqAvgCost: deqAvgCost,
    deqNoDrawCost: deqNoDrawCost,
    deqFastCost: deqFastCost,
    deq: function deq(self, pxRatio) {
      return self.dequeue(pxRatio);
    },
    onDeqd: noop$1,
    shouldRedraw: trueify,
    priority: function priority(self) {
      return self.renderer.beforeRenderPriorities.lyrTxrDeq;
    }
  });

  var CRp$a = {};
  var impl;
  function polygon(context, points) {
    for (var i = 0; i < points.length; i++) {
      var pt = points[i];
      context.lineTo(pt.x, pt.y);
    }
  }
  function triangleBackcurve(context, points, controlPoint) {
    var firstPt;
    for (var i = 0; i < points.length; i++) {
      var pt = points[i];
      if (i === 0) {
        firstPt = pt;
      }
      context.lineTo(pt.x, pt.y);
    }
    context.quadraticCurveTo(controlPoint.x, controlPoint.y, firstPt.x, firstPt.y);
  }
  function triangleTee(context, trianglePoints, teePoints) {
    if (context.beginPath) {
      context.beginPath();
    }
    var triPts = trianglePoints;
    for (var i = 0; i < triPts.length; i++) {
      var pt = triPts[i];
      context.lineTo(pt.x, pt.y);
    }
    var teePts = teePoints;
    var firstTeePt = teePoints[0];
    context.moveTo(firstTeePt.x, firstTeePt.y);
    for (var i = 1; i < teePts.length; i++) {
      var pt = teePts[i];
      context.lineTo(pt.x, pt.y);
    }
    if (context.closePath) {
      context.closePath();
    }
  }
  function circleTriangle(context, trianglePoints, rx, ry, r) {
    if (context.beginPath) {
      context.beginPath();
    }
    context.arc(rx, ry, r, 0, Math.PI * 2, false);
    var triPts = trianglePoints;
    var firstTrPt = triPts[0];
    context.moveTo(firstTrPt.x, firstTrPt.y);
    for (var i = 0; i < triPts.length; i++) {
      var pt = triPts[i];
      context.lineTo(pt.x, pt.y);
    }
    if (context.closePath) {
      context.closePath();
    }
  }
  function circle(context, rx, ry, r) {
    context.arc(rx, ry, r, 0, Math.PI * 2, false);
  }
  CRp$a.arrowShapeImpl = function (name) {
    return (impl || (impl = {
      'polygon': polygon,
      'triangle-backcurve': triangleBackcurve,
      'triangle-tee': triangleTee,
      'circle-triangle': circleTriangle,
      'triangle-cross': triangleTee,
      'circle': circle
    }))[name];
  };

  var CRp$9 = {};
  CRp$9.drawElement = function (context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity) {
    var r = this;
    if (ele.isNode()) {
      r.drawNode(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);
    } else {
      r.drawEdge(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);
    }
  };
  CRp$9.drawElementOverlay = function (context, ele) {
    var r = this;
    if (ele.isNode()) {
      r.drawNodeOverlay(context, ele);
    } else {
      r.drawEdgeOverlay(context, ele);
    }
  };
  CRp$9.drawElementUnderlay = function (context, ele) {
    var r = this;
    if (ele.isNode()) {
      r.drawNodeUnderlay(context, ele);
    } else {
      r.drawEdgeUnderlay(context, ele);
    }
  };
  CRp$9.drawCachedElementPortion = function (context, ele, eleTxrCache, pxRatio, lvl, reason, getRotation, getOpacity) {
    var r = this;
    var bb = eleTxrCache.getBoundingBox(ele);
    if (bb.w === 0 || bb.h === 0) {
      return;
    } // ignore zero size case

    var eleCache = eleTxrCache.getElement(ele, bb, pxRatio, lvl, reason);
    if (eleCache != null) {
      var opacity = getOpacity(r, ele);
      if (opacity === 0) {
        return;
      }
      var theta = getRotation(r, ele);
      var x1 = bb.x1,
        y1 = bb.y1,
        w = bb.w,
        h = bb.h;
      var x, y, sx, sy, smooth;
      if (theta !== 0) {
        var rotPt = eleTxrCache.getRotationPoint(ele);
        sx = rotPt.x;
        sy = rotPt.y;
        context.translate(sx, sy);
        context.rotate(theta);
        smooth = r.getImgSmoothing(context);
        if (!smooth) {
          r.setImgSmoothing(context, true);
        }
        var off = eleTxrCache.getRotationOffset(ele);
        x = off.x;
        y = off.y;
      } else {
        x = x1;
        y = y1;
      }
      var oldGlobalAlpha;
      if (opacity !== 1) {
        oldGlobalAlpha = context.globalAlpha;
        context.globalAlpha = oldGlobalAlpha * opacity;
      }
      context.drawImage(eleCache.texture.canvas, eleCache.x, 0, eleCache.width, eleCache.height, x, y, w, h);
      if (opacity !== 1) {
        context.globalAlpha = oldGlobalAlpha;
      }
      if (theta !== 0) {
        context.rotate(-theta);
        context.translate(-sx, -sy);
        if (!smooth) {
          r.setImgSmoothing(context, false);
        }
      }
    } else {
      eleTxrCache.drawElement(context, ele); // direct draw fallback
    }
  };

  var getZeroRotation = function getZeroRotation() {
    return 0;
  };
  var getLabelRotation = function getLabelRotation(r, ele) {
    return r.getTextAngle(ele, null);
  };
  var getSourceLabelRotation = function getSourceLabelRotation(r, ele) {
    return r.getTextAngle(ele, 'source');
  };
  var getTargetLabelRotation = function getTargetLabelRotation(r, ele) {
    return r.getTextAngle(ele, 'target');
  };
  var getOpacity = function getOpacity(r, ele) {
    return ele.effectiveOpacity();
  };
  var getTextOpacity = function getTextOpacity(e, ele) {
    return ele.pstyle('text-opacity').pfValue * ele.effectiveOpacity();
  };
  CRp$9.drawCachedElement = function (context, ele, pxRatio, extent, lvl, requestHighQuality) {
    var r = this;
    var _r$data = r.data,
      eleTxrCache = _r$data.eleTxrCache,
      lblTxrCache = _r$data.lblTxrCache,
      slbTxrCache = _r$data.slbTxrCache,
      tlbTxrCache = _r$data.tlbTxrCache;
    var bb = ele.boundingBox();
    var reason = requestHighQuality === true ? eleTxrCache.reasons.highQuality : null;
    if (bb.w === 0 || bb.h === 0 || !ele.visible()) {
      return;
    }
    if (!extent || boundingBoxesIntersect(bb, extent)) {
      var isEdge = ele.isEdge();
      var badLine = ele.element()._private.rscratch.badLine;
      r.drawElementUnderlay(context, ele);
      r.drawCachedElementPortion(context, ele, eleTxrCache, pxRatio, lvl, reason, getZeroRotation, getOpacity);
      if (!isEdge || !badLine) {
        r.drawCachedElementPortion(context, ele, lblTxrCache, pxRatio, lvl, reason, getLabelRotation, getTextOpacity);
      }
      if (isEdge && !badLine) {
        r.drawCachedElementPortion(context, ele, slbTxrCache, pxRatio, lvl, reason, getSourceLabelRotation, getTextOpacity);
        r.drawCachedElementPortion(context, ele, tlbTxrCache, pxRatio, lvl, reason, getTargetLabelRotation, getTextOpacity);
      }
      r.drawElementOverlay(context, ele);
    }
  };
  CRp$9.drawElements = function (context, eles) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      r.drawElement(context, ele);
    }
  };
  CRp$9.drawCachedElements = function (context, eles, pxRatio, extent) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      r.drawCachedElement(context, ele, pxRatio, extent);
    }
  };
  CRp$9.drawCachedNodes = function (context, eles, pxRatio, extent) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (!ele.isNode()) {
        continue;
      }
      r.drawCachedElement(context, ele, pxRatio, extent);
    }
  };
  CRp$9.drawLayeredElements = function (context, eles, pxRatio, extent) {
    var r = this;
    var layers = r.data.lyrTxrCache.getLayers(eles, pxRatio);
    if (layers) {
      for (var i = 0; i < layers.length; i++) {
        var layer = layers[i];
        var bb = layer.bb;
        if (bb.w === 0 || bb.h === 0) {
          continue;
        }
        context.drawImage(layer.canvas, bb.x1, bb.y1, bb.w, bb.h);
      }
    } else {
      // fall back on plain caching if no layers
      r.drawCachedElements(context, eles, pxRatio, extent);
    }
  };

  /* global Path2D */
  var CRp$8 = {};
  CRp$8.drawEdge = function (context, edge, shiftToOriginWithBb) {
    var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    var rs = edge._private.rscratch;
    if (shouldDrawOpacity && !edge.visible()) {
      return;
    }

    // if bezier ctrl pts can not be calculated, then die
    if (rs.badLine || rs.allpts == null || isNaN(rs.allpts[0])) {
      // isNaN in case edge is impossible and browser bugs (e.g. safari)
      return;
    }
    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }
    var opacity = shouldDrawOpacity ? edge.pstyle('opacity').value : 1;
    var lineOpacity = shouldDrawOpacity ? edge.pstyle('line-opacity').value : 1;
    var curveStyle = edge.pstyle('curve-style').value;
    var lineStyle = edge.pstyle('line-style').value;
    var edgeWidth = edge.pstyle('width').pfValue;
    var lineCap = edge.pstyle('line-cap').value;
    var effectiveLineOpacity = opacity * lineOpacity;
    // separate arrow opacity would require arrow-opacity property
    var effectiveArrowOpacity = opacity * lineOpacity;
    var drawLine = function drawLine() {
      var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity;
      if (curveStyle === 'straight-triangle') {
        r.eleStrokeStyle(context, edge, strokeOpacity);
        r.drawEdgeTrianglePath(edge, context, rs.allpts);
      } else {
        context.lineWidth = edgeWidth;
        context.lineCap = lineCap;
        r.eleStrokeStyle(context, edge, strokeOpacity);
        r.drawEdgePath(edge, context, rs.allpts, lineStyle);
        context.lineCap = 'butt'; // reset for other drawing functions
      }
    };

    var drawOverlay = function drawOverlay() {
      if (!shouldDrawOverlay) {
        return;
      }
      r.drawEdgeOverlay(context, edge);
    };
    var drawUnderlay = function drawUnderlay() {
      if (!shouldDrawOverlay) {
        return;
      }
      r.drawEdgeUnderlay(context, edge);
    };
    var drawArrows = function drawArrows() {
      var arrowOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveArrowOpacity;
      r.drawArrowheads(context, edge, arrowOpacity);
    };
    var drawText = function drawText() {
      r.drawElementText(context, edge, null, drawLabel);
    };
    context.lineJoin = 'round';
    var ghost = edge.pstyle('ghost').value === 'yes';
    if (ghost) {
      var gx = edge.pstyle('ghost-offset-x').pfValue;
      var gy = edge.pstyle('ghost-offset-y').pfValue;
      var ghostOpacity = edge.pstyle('ghost-opacity').value;
      var effectiveGhostOpacity = effectiveLineOpacity * ghostOpacity;
      context.translate(gx, gy);
      drawLine(effectiveGhostOpacity);
      drawArrows(effectiveGhostOpacity);
      context.translate(-gx, -gy);
    }
    drawUnderlay();
    drawLine();
    drawArrows();
    drawOverlay();
    drawText();
    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  var drawEdgeOverlayUnderlay = function drawEdgeOverlayUnderlay(overlayOrUnderlay) {
    if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {
      throw new Error('Invalid state');
    }
    return function (context, edge) {
      if (!edge.visible()) {
        return;
      }
      var opacity = edge.pstyle("".concat(overlayOrUnderlay, "-opacity")).value;
      if (opacity === 0) {
        return;
      }
      var r = this;
      var usePaths = r.usePaths();
      var rs = edge._private.rscratch;
      var padding = edge.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue;
      var width = 2 * padding;
      var color = edge.pstyle("".concat(overlayOrUnderlay, "-color")).value;
      context.lineWidth = width;
      if (rs.edgeType === 'self' && !usePaths) {
        context.lineCap = 'butt';
      } else {
        context.lineCap = 'round';
      }
      r.colorStrokeStyle(context, color[0], color[1], color[2], opacity);
      r.drawEdgePath(edge, context, rs.allpts, 'solid');
    };
  };
  CRp$8.drawEdgeOverlay = drawEdgeOverlayUnderlay('overlay');
  CRp$8.drawEdgeUnderlay = drawEdgeOverlayUnderlay('underlay');
  CRp$8.drawEdgePath = function (edge, context, pts, type) {
    var rs = edge._private.rscratch;
    var canvasCxt = context;
    var path;
    var pathCacheHit = false;
    var usePaths = this.usePaths();
    var lineDashPattern = edge.pstyle('line-dash-pattern').pfValue;
    var lineDashOffset = edge.pstyle('line-dash-offset').pfValue;
    if (usePaths) {
      var pathCacheKey = pts.join('$');
      var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;
      if (keyMatches) {
        path = context = rs.pathCache;
        pathCacheHit = true;
      } else {
        path = context = new Path2D();
        rs.pathCacheKey = pathCacheKey;
        rs.pathCache = path;
      }
    }
    if (canvasCxt.setLineDash) {
      // for very outofdate browsers
      switch (type) {
        case 'dotted':
          canvasCxt.setLineDash([1, 1]);
          break;
        case 'dashed':
          canvasCxt.setLineDash(lineDashPattern);
          canvasCxt.lineDashOffset = lineDashOffset;
          break;
        case 'solid':
          canvasCxt.setLineDash([]);
          break;
      }
    }
    if (!pathCacheHit && !rs.badLine) {
      if (context.beginPath) {
        context.beginPath();
      }
      context.moveTo(pts[0], pts[1]);
      switch (rs.edgeType) {
        case 'bezier':
        case 'self':
        case 'compound':
        case 'multibezier':
          for (var i = 2; i + 3 < pts.length; i += 4) {
            context.quadraticCurveTo(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]);
          }
          break;
        case 'straight':
        case 'segments':
        case 'haystack':
          for (var _i = 2; _i + 1 < pts.length; _i += 2) {
            context.lineTo(pts[_i], pts[_i + 1]);
          }
          break;
      }
    }
    context = canvasCxt;
    if (usePaths) {
      context.stroke(path);
    } else {
      context.stroke();
    }

    // reset any line dashes
    if (context.setLineDash) {
      // for very outofdate browsers
      context.setLineDash([]);
    }
  };
  CRp$8.drawEdgeTrianglePath = function (edge, context, pts) {
    // use line stroke style for triangle fill style
    context.fillStyle = context.strokeStyle;
    var edgeWidth = edge.pstyle('width').pfValue;
    for (var i = 0; i + 1 < pts.length; i += 2) {
      var vector = [pts[i + 2] - pts[i], pts[i + 3] - pts[i + 1]];
      var length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
      var normal = [vector[1] / length, -vector[0] / length];
      var triangleHead = [normal[0] * edgeWidth / 2, normal[1] * edgeWidth / 2];
      context.beginPath();
      context.moveTo(pts[i] - triangleHead[0], pts[i + 1] - triangleHead[1]);
      context.lineTo(pts[i] + triangleHead[0], pts[i + 1] + triangleHead[1]);
      context.lineTo(pts[i + 2], pts[i + 3]);
      context.closePath();
      context.fill();
    }
  };
  CRp$8.drawArrowheads = function (context, edge, opacity) {
    var rs = edge._private.rscratch;
    var isHaystack = rs.edgeType === 'haystack';
    if (!isHaystack) {
      this.drawArrowhead(context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity);
    }
    this.drawArrowhead(context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity);
    this.drawArrowhead(context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity);
    if (!isHaystack) {
      this.drawArrowhead(context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity);
    }
  };
  CRp$8.drawArrowhead = function (context, edge, prefix, x, y, angle, opacity) {
    if (isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null) {
      return;
    }
    var self = this;
    var arrowShape = edge.pstyle(prefix + '-arrow-shape').value;
    if (arrowShape === 'none') {
      return;
    }
    var arrowClearFill = edge.pstyle(prefix + '-arrow-fill').value === 'hollow' ? 'both' : 'filled';
    var arrowFill = edge.pstyle(prefix + '-arrow-fill').value;
    var edgeWidth = edge.pstyle('width').pfValue;
    var pArrowWidth = edge.pstyle(prefix + '-arrow-width');
    var arrowWidth = pArrowWidth.value === 'match-line' ? edgeWidth : pArrowWidth.pfValue;
    if (pArrowWidth.units === '%') arrowWidth *= edgeWidth;
    var edgeOpacity = edge.pstyle('opacity').value;
    if (opacity === undefined) {
      opacity = edgeOpacity;
    }
    var gco = context.globalCompositeOperation;
    if (opacity !== 1 || arrowFill === 'hollow') {
      // then extra clear is needed
      context.globalCompositeOperation = 'destination-out';
      self.colorFillStyle(context, 255, 255, 255, 1);
      self.colorStrokeStyle(context, 255, 255, 255, 1);
      self.drawArrowShape(edge, context, arrowClearFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);
      context.globalCompositeOperation = gco;
    } // otherwise, the opaque arrow clears it for free :)

    var color = edge.pstyle(prefix + '-arrow-color').value;
    self.colorFillStyle(context, color[0], color[1], color[2], opacity);
    self.colorStrokeStyle(context, color[0], color[1], color[2], opacity);
    self.drawArrowShape(edge, context, arrowFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);
  };
  CRp$8.drawArrowShape = function (edge, context, fill, edgeWidth, shape, shapeWidth, x, y, angle) {
    var r = this;
    var usePaths = this.usePaths() && shape !== 'triangle-cross';
    var pathCacheHit = false;
    var path;
    var canvasContext = context;
    var translation = {
      x: x,
      y: y
    };
    var scale = edge.pstyle('arrow-scale').value;
    var size = this.getArrowWidth(edgeWidth, scale);
    var shapeImpl = r.arrowShapes[shape];
    if (usePaths) {
      var cache = r.arrowPathCache = r.arrowPathCache || [];
      var key = hashString(shape);
      var cachedPath = cache[key];
      if (cachedPath != null) {
        path = context = cachedPath;
        pathCacheHit = true;
      } else {
        path = context = new Path2D();
        cache[key] = path;
      }
    }
    if (!pathCacheHit) {
      if (context.beginPath) {
        context.beginPath();
      }
      if (usePaths) {
        // store in the path cache with values easily manipulated later
        shapeImpl.draw(context, 1, 0, {
          x: 0,
          y: 0
        }, 1);
      } else {
        shapeImpl.draw(context, size, angle, translation, edgeWidth);
      }
      if (context.closePath) {
        context.closePath();
      }
    }
    context = canvasContext;
    if (usePaths) {
      // set transform to arrow position/orientation
      context.translate(x, y);
      context.rotate(angle);
      context.scale(size, size);
    }
    if (fill === 'filled' || fill === 'both') {
      if (usePaths) {
        context.fill(path);
      } else {
        context.fill();
      }
    }
    if (fill === 'hollow' || fill === 'both') {
      context.lineWidth = shapeWidth / (usePaths ? size : 1);
      context.lineJoin = 'miter';
      if (usePaths) {
        context.stroke(path);
      } else {
        context.stroke();
      }
    }
    if (usePaths) {
      // reset transform by applying inverse
      context.scale(1 / size, 1 / size);
      context.rotate(-angle);
      context.translate(-x, -y);
    }
  };

  var CRp$7 = {};
  CRp$7.safeDrawImage = function (context, img, ix, iy, iw, ih, x, y, w, h) {
    // detect problematic cases for old browsers with bad images (cheaper than try-catch)
    if (iw <= 0 || ih <= 0 || w <= 0 || h <= 0) {
      return;
    }
    try {
      context.drawImage(img, ix, iy, iw, ih, x, y, w, h);
    } catch (e) {
      warn(e);
    }
  };
  CRp$7.drawInscribedImage = function (context, img, node, index, nodeOpacity) {
    var r = this;
    var pos = node.position();
    var nodeX = pos.x;
    var nodeY = pos.y;
    var styleObj = node.cy().style();
    var getIndexedStyle = styleObj.getIndexedStyle.bind(styleObj);
    var fit = getIndexedStyle(node, 'background-fit', 'value', index);
    var repeat = getIndexedStyle(node, 'background-repeat', 'value', index);
    var nodeW = node.width();
    var nodeH = node.height();
    var paddingX2 = node.padding() * 2;
    var nodeTW = nodeW + (getIndexedStyle(node, 'background-width-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);
    var nodeTH = nodeH + (getIndexedStyle(node, 'background-height-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);
    var rs = node._private.rscratch;
    var clip = getIndexedStyle(node, 'background-clip', 'value', index);
    var shouldClip = clip === 'node';
    var imgOpacity = getIndexedStyle(node, 'background-image-opacity', 'value', index) * nodeOpacity;
    var smooth = getIndexedStyle(node, 'background-image-smoothing', 'value', index);
    var imgW = img.width || img.cachedW;
    var imgH = img.height || img.cachedH;

    // workaround for broken browsers like ie
    if (null == imgW || null == imgH) {
      document.body.appendChild(img); // eslint-disable-line no-undef

      imgW = img.cachedW = img.width || img.offsetWidth;
      imgH = img.cachedH = img.height || img.offsetHeight;
      document.body.removeChild(img); // eslint-disable-line no-undef
    }

    var w = imgW;
    var h = imgH;
    if (getIndexedStyle(node, 'background-width', 'value', index) !== 'auto') {
      if (getIndexedStyle(node, 'background-width', 'units', index) === '%') {
        w = getIndexedStyle(node, 'background-width', 'pfValue', index) * nodeTW;
      } else {
        w = getIndexedStyle(node, 'background-width', 'pfValue', index);
      }
    }
    if (getIndexedStyle(node, 'background-height', 'value', index) !== 'auto') {
      if (getIndexedStyle(node, 'background-height', 'units', index) === '%') {
        h = getIndexedStyle(node, 'background-height', 'pfValue', index) * nodeTH;
      } else {
        h = getIndexedStyle(node, 'background-height', 'pfValue', index);
      }
    }
    if (w === 0 || h === 0) {
      return; // no point in drawing empty image (and chrome is broken in this case)
    }

    if (fit === 'contain') {
      var scale = Math.min(nodeTW / w, nodeTH / h);
      w *= scale;
      h *= scale;
    } else if (fit === 'cover') {
      var scale = Math.max(nodeTW / w, nodeTH / h);
      w *= scale;
      h *= scale;
    }
    var x = nodeX - nodeTW / 2; // left
    var posXUnits = getIndexedStyle(node, 'background-position-x', 'units', index);
    var posXPfVal = getIndexedStyle(node, 'background-position-x', 'pfValue', index);
    if (posXUnits === '%') {
      x += (nodeTW - w) * posXPfVal;
    } else {
      x += posXPfVal;
    }
    var offXUnits = getIndexedStyle(node, 'background-offset-x', 'units', index);
    var offXPfVal = getIndexedStyle(node, 'background-offset-x', 'pfValue', index);
    if (offXUnits === '%') {
      x += (nodeTW - w) * offXPfVal;
    } else {
      x += offXPfVal;
    }
    var y = nodeY - nodeTH / 2; // top
    var posYUnits = getIndexedStyle(node, 'background-position-y', 'units', index);
    var posYPfVal = getIndexedStyle(node, 'background-position-y', 'pfValue', index);
    if (posYUnits === '%') {
      y += (nodeTH - h) * posYPfVal;
    } else {
      y += posYPfVal;
    }
    var offYUnits = getIndexedStyle(node, 'background-offset-y', 'units', index);
    var offYPfVal = getIndexedStyle(node, 'background-offset-y', 'pfValue', index);
    if (offYUnits === '%') {
      y += (nodeTH - h) * offYPfVal;
    } else {
      y += offYPfVal;
    }
    if (rs.pathCache) {
      x -= nodeX;
      y -= nodeY;
      nodeX = 0;
      nodeY = 0;
    }
    var gAlpha = context.globalAlpha;
    context.globalAlpha = imgOpacity;
    var smoothingEnabled = r.getImgSmoothing(context);
    var isSmoothingSwitched = false;
    if (smooth === 'no' && smoothingEnabled) {
      r.setImgSmoothing(context, false);
      isSmoothingSwitched = true;
    } else if (smooth === 'yes' && !smoothingEnabled) {
      r.setImgSmoothing(context, true);
      isSmoothingSwitched = true;
    }
    if (repeat === 'no-repeat') {
      if (shouldClip) {
        context.save();
        if (rs.pathCache) {
          context.clip(rs.pathCache);
        } else {
          r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH);
          context.clip();
        }
      }
      r.safeDrawImage(context, img, 0, 0, imgW, imgH, x, y, w, h);
      if (shouldClip) {
        context.restore();
      }
    } else {
      var pattern = context.createPattern(img, repeat);
      context.fillStyle = pattern;
      r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH);
      context.translate(x, y);
      context.fill();
      context.translate(-x, -y);
    }
    context.globalAlpha = gAlpha;
    if (isSmoothingSwitched) {
      r.setImgSmoothing(context, smoothingEnabled);
    }
  };

  var CRp$6 = {};
  CRp$6.eleTextBiggerThanMin = function (ele, scale) {
    if (!scale) {
      var zoom = ele.cy().zoom();
      var pxRatio = this.getPixelRatio();
      var lvl = Math.ceil(log2(zoom * pxRatio)); // the effective texture level

      scale = Math.pow(2, lvl);
    }
    var computedSize = ele.pstyle('font-size').pfValue * scale;
    var minSize = ele.pstyle('min-zoomed-font-size').pfValue;
    if (computedSize < minSize) {
      return false;
    }
    return true;
  };
  CRp$6.drawElementText = function (context, ele, shiftToOriginWithBb, force, prefix) {
    var useEleOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    if (force == null) {
      if (useEleOpacity && !r.eleTextBiggerThanMin(ele)) {
        return;
      }
    } else if (force === false) {
      return;
    }
    if (ele.isNode()) {
      var label = ele.pstyle('label');
      if (!label || !label.value) {
        return;
      }
      var justification = r.getLabelJustification(ele);
      context.textAlign = justification;
      context.textBaseline = 'bottom';
    } else {
      var badLine = ele.element()._private.rscratch.badLine;
      var _label = ele.pstyle('label');
      var srcLabel = ele.pstyle('source-label');
      var tgtLabel = ele.pstyle('target-label');
      if (badLine || (!_label || !_label.value) && (!srcLabel || !srcLabel.value) && (!tgtLabel || !tgtLabel.value)) {
        return;
      }
      context.textAlign = 'center';
      context.textBaseline = 'bottom';
    }
    var applyRotation = !shiftToOriginWithBb;
    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }
    if (prefix == null) {
      r.drawText(context, ele, null, applyRotation, useEleOpacity);
      if (ele.isEdge()) {
        r.drawText(context, ele, 'source', applyRotation, useEleOpacity);
        r.drawText(context, ele, 'target', applyRotation, useEleOpacity);
      }
    } else {
      r.drawText(context, ele, prefix, applyRotation, useEleOpacity);
    }
    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  CRp$6.getFontCache = function (context) {
    var cache;
    this.fontCaches = this.fontCaches || [];
    for (var i = 0; i < this.fontCaches.length; i++) {
      cache = this.fontCaches[i];
      if (cache.context === context) {
        return cache;
      }
    }
    cache = {
      context: context
    };
    this.fontCaches.push(cache);
    return cache;
  };

  // set up canvas context with font
  // returns transformed text string
  CRp$6.setupTextStyle = function (context, ele) {
    var useEleOpacity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    // Font style
    var labelStyle = ele.pstyle('font-style').strValue;
    var labelSize = ele.pstyle('font-size').pfValue + 'px';
    var labelFamily = ele.pstyle('font-family').strValue;
    var labelWeight = ele.pstyle('font-weight').strValue;
    var opacity = useEleOpacity ? ele.effectiveOpacity() * ele.pstyle('text-opacity').value : 1;
    var outlineOpacity = ele.pstyle('text-outline-opacity').value * opacity;
    var color = ele.pstyle('color').value;
    var outlineColor = ele.pstyle('text-outline-color').value;
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;
    context.lineJoin = 'round'; // so text outlines aren't jagged

    this.colorFillStyle(context, color[0], color[1], color[2], opacity);
    this.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity);
  };

  // TODO ensure re-used
  function roundRect(ctx, x, y, width, height) {
    var radius = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 5;
    var stroke = arguments.length > 6 ? arguments[6] : undefined;
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    if (stroke) ctx.stroke();else ctx.fill();
  }
  CRp$6.getTextAngle = function (ele, prefix) {
    var theta;
    var _p = ele._private;
    var rscratch = _p.rscratch;
    var pdash = prefix ? prefix + '-' : '';
    var rotation = ele.pstyle(pdash + 'text-rotation');
    var textAngle = getPrefixedProperty(rscratch, 'labelAngle', prefix);
    if (rotation.strValue === 'autorotate') {
      theta = ele.isEdge() ? textAngle : 0;
    } else if (rotation.strValue === 'none') {
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }
    return theta;
  };
  CRp$6.drawText = function (context, ele, prefix) {
    var applyRotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var useEleOpacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var _p = ele._private;
    var rscratch = _p.rscratch;
    var parentOpacity = useEleOpacity ? ele.effectiveOpacity() : 1;
    if (useEleOpacity && (parentOpacity === 0 || ele.pstyle('text-opacity').value === 0)) {
      return;
    }

    // use 'main' as an alias for the main label (i.e. null prefix)
    if (prefix === 'main') {
      prefix = null;
    }
    var textX = getPrefixedProperty(rscratch, 'labelX', prefix);
    var textY = getPrefixedProperty(rscratch, 'labelY', prefix);
    var orgTextX, orgTextY; // used for rotation
    var text = this.getLabelText(ele, prefix);
    if (text != null && text !== '' && !isNaN(textX) && !isNaN(textY)) {
      this.setupTextStyle(context, ele, useEleOpacity);
      var pdash = prefix ? prefix + '-' : '';
      var textW = getPrefixedProperty(rscratch, 'labelWidth', prefix);
      var textH = getPrefixedProperty(rscratch, 'labelHeight', prefix);
      var marginX = ele.pstyle(pdash + 'text-margin-x').pfValue;
      var marginY = ele.pstyle(pdash + 'text-margin-y').pfValue;
      var isEdge = ele.isEdge();
      var halign = ele.pstyle('text-halign').value;
      var valign = ele.pstyle('text-valign').value;
      if (isEdge) {
        halign = 'center';
        valign = 'center';
      }
      textX += marginX;
      textY += marginY;
      var theta;
      if (!applyRotation) {
        theta = 0;
      } else {
        theta = this.getTextAngle(ele, prefix);
      }
      if (theta !== 0) {
        orgTextX = textX;
        orgTextY = textY;
        context.translate(orgTextX, orgTextY);
        context.rotate(theta);
        textX = 0;
        textY = 0;
      }
      switch (valign) {
        case 'top':
          break;
        case 'center':
          textY += textH / 2;
          break;
        case 'bottom':
          textY += textH;
          break;
      }
      var backgroundOpacity = ele.pstyle('text-background-opacity').value;
      var borderOpacity = ele.pstyle('text-border-opacity').value;
      var textBorderWidth = ele.pstyle('text-border-width').pfValue;
      var backgroundPadding = ele.pstyle('text-background-padding').pfValue;
      var styleShape = ele.pstyle('text-background-shape').strValue;
      var rounded = styleShape.indexOf('round') === 0;
      var roundRadius = 2;
      if (backgroundOpacity > 0 || textBorderWidth > 0 && borderOpacity > 0) {
        var bgX = textX - backgroundPadding;
        switch (halign) {
          case 'left':
            bgX -= textW;
            break;
          case 'center':
            bgX -= textW / 2;
            break;
        }
        var bgY = textY - textH - backgroundPadding;
        var bgW = textW + 2 * backgroundPadding;
        var bgH = textH + 2 * backgroundPadding;
        if (backgroundOpacity > 0) {
          var textFill = context.fillStyle;
          var textBackgroundColor = ele.pstyle('text-background-color').value;
          context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')';
          if (rounded) {
            roundRect(context, bgX, bgY, bgW, bgH, roundRadius);
          } else {
            context.fillRect(bgX, bgY, bgW, bgH);
          }
          context.fillStyle = textFill;
        }
        if (textBorderWidth > 0 && borderOpacity > 0) {
          var textStroke = context.strokeStyle;
          var textLineWidth = context.lineWidth;
          var textBorderColor = ele.pstyle('text-border-color').value;
          var textBorderStyle = ele.pstyle('text-border-style').value;
          context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')';
          context.lineWidth = textBorderWidth;
          if (context.setLineDash) {
            // for very outofdate browsers
            switch (textBorderStyle) {
              case 'dotted':
                context.setLineDash([1, 1]);
                break;
              case 'dashed':
                context.setLineDash([4, 2]);
                break;
              case 'double':
                context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
                context.setLineDash([]);
                break;
              case 'solid':
                context.setLineDash([]);
                break;
            }
          }
          if (rounded) {
            roundRect(context, bgX, bgY, bgW, bgH, roundRadius, 'stroke');
          } else {
            context.strokeRect(bgX, bgY, bgW, bgH);
          }
          if (textBorderStyle === 'double') {
            var whiteWidth = textBorderWidth / 2;
            if (rounded) {
              roundRect(context, bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2, roundRadius, 'stroke');
            } else {
              context.strokeRect(bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2);
            }
          }
          if (context.setLineDash) {
            // for very outofdate browsers
            context.setLineDash([]);
          }
          context.lineWidth = textLineWidth;
          context.strokeStyle = textStroke;
        }
      }
      var lineWidth = 2 * ele.pstyle('text-outline-width').pfValue; // *2 b/c the stroke is drawn centred on the middle

      if (lineWidth > 0) {
        context.lineWidth = lineWidth;
      }
      if (ele.pstyle('text-wrap').value === 'wrap') {
        var lines = getPrefixedProperty(rscratch, 'labelWrapCachedLines', prefix);
        var lineHeight = getPrefixedProperty(rscratch, 'labelLineHeight', prefix);
        var halfTextW = textW / 2;
        var justification = this.getLabelJustification(ele);
        if (justification === 'auto') ; else if (halign === 'left') {
          // auto justification : right
          if (justification === 'left') {
            textX += -textW;
          } else if (justification === 'center') {
            textX += -halfTextW;
          } // else same as auto
        } else if (halign === 'center') {
          // auto justfication : center
          if (justification === 'left') {
            textX += -halfTextW;
          } else if (justification === 'right') {
            textX += halfTextW;
          } // else same as auto
        } else if (halign === 'right') {
          // auto justification : left
          if (justification === 'center') {
            textX += halfTextW;
          } else if (justification === 'right') {
            textX += textW;
          } // else same as auto
        }

        switch (valign) {
          case 'top':
            textY -= (lines.length - 1) * lineHeight;
            break;
          case 'center':
          case 'bottom':
            textY -= (lines.length - 1) * lineHeight;
            break;
        }
        for (var l = 0; l < lines.length; l++) {
          if (lineWidth > 0) {
            context.strokeText(lines[l], textX, textY);
          }
          context.fillText(lines[l], textX, textY);
          textY += lineHeight;
        }
      } else {
        if (lineWidth > 0) {
          context.strokeText(text, textX, textY);
        }
        context.fillText(text, textX, textY);
      }
      if (theta !== 0) {
        context.rotate(-theta);
        context.translate(-orgTextX, -orgTextY);
      }
    }
  };

  /* global Path2D */
  var CRp$5 = {};
  CRp$5.drawNode = function (context, node, shiftToOriginWithBb) {
    var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    var nodeWidth, nodeHeight;
    var _p = node._private;
    var rs = _p.rscratch;
    var pos = node.position();
    if (!number$1(pos.x) || !number$1(pos.y)) {
      return; // can't draw node with undefined position
    }

    if (shouldDrawOpacity && !node.visible()) {
      return;
    }
    var eleOpacity = shouldDrawOpacity ? node.effectiveOpacity() : 1;
    var usePaths = r.usePaths();
    var path;
    var pathCacheHit = false;
    var padding = node.padding();
    nodeWidth = node.width() + 2 * padding;
    nodeHeight = node.height() + 2 * padding;

    //
    // setup shift

    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }

    //
    // load bg image

    var bgImgProp = node.pstyle('background-image');
    var urls = bgImgProp.value;
    var urlDefined = new Array(urls.length);
    var image = new Array(urls.length);
    var numImages = 0;
    for (var i = 0; i < urls.length; i++) {
      var url = urls[i];
      var defd = urlDefined[i] = url != null && url !== 'none';
      if (defd) {
        var bgImgCrossOrigin = node.cy().style().getIndexedStyle(node, 'background-image-crossorigin', 'value', i);
        numImages++;

        // get image, and if not loaded then ask to redraw when later loaded
        image[i] = r.getCachedImage(url, bgImgCrossOrigin, function () {
          _p.backgroundTimestamp = Date.now();
          node.emitAndNotify('background');
        });
      }
    }

    //
    // setup styles

    var darkness = node.pstyle('background-blacken').value;
    var borderWidth = node.pstyle('border-width').pfValue;
    var bgOpacity = node.pstyle('background-opacity').value * eleOpacity;
    var borderColor = node.pstyle('border-color').value;
    var borderStyle = node.pstyle('border-style').value;
    var borderOpacity = node.pstyle('border-opacity').value * eleOpacity;
    var outlineWidth = node.pstyle('outline-width').pfValue;
    var outlineColor = node.pstyle('outline-color').value;
    var outlineStyle = node.pstyle('outline-style').value;
    var outlineOpacity = node.pstyle('outline-opacity').value * eleOpacity;
    var outlineOffset = node.pstyle('outline-offset').value;
    context.lineJoin = 'miter'; // so borders are square with the node shape

    var setupShapeColor = function setupShapeColor() {
      var bgOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : bgOpacity;
      r.eleFillStyle(context, node, bgOpy);
    };
    var setupBorderColor = function setupBorderColor() {
      var bdrOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : borderOpacity;
      r.colorStrokeStyle(context, borderColor[0], borderColor[1], borderColor[2], bdrOpy);
    };
    var setupOutlineColor = function setupOutlineColor() {
      var otlnOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : outlineOpacity;
      r.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], otlnOpy);
    };

    //
    // setup shape

    var getPath = function getPath(width, height, shape, points) {
      var pathCache = r.nodePathCache = r.nodePathCache || [];
      var key = hashStrings(shape === 'polygon' ? shape + ',' + points.join(',') : shape, '' + height, '' + width);
      var cachedPath = pathCache[key];
      var path;
      var cacheHit = false;
      if (cachedPath != null) {
        path = cachedPath;
        cacheHit = true;
        rs.pathCache = path;
      } else {
        path = new Path2D();
        pathCache[key] = rs.pathCache = path;
      }
      return {
        path: path,
        cacheHit: cacheHit
      };
    };
    var styleShape = node.pstyle('shape').strValue;
    var shapePts = node.pstyle('shape-polygon-points').pfValue;
    if (usePaths) {
      context.translate(pos.x, pos.y);
      var shapePath = getPath(nodeWidth, nodeHeight, styleShape, shapePts);
      path = shapePath.path;
      pathCacheHit = shapePath.cacheHit;
    }
    var drawShape = function drawShape() {
      if (!pathCacheHit) {
        var npos = pos;
        if (usePaths) {
          npos = {
            x: 0,
            y: 0
          };
        }
        r.nodeShapes[r.getNodeShape(node)].draw(path || context, npos.x, npos.y, nodeWidth, nodeHeight);
      }
      if (usePaths) {
        context.fill(path);
      } else {
        context.fill();
      }
    };
    var drawImages = function drawImages() {
      var nodeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;
      var inside = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var prevBging = _p.backgrounding;
      var totalCompleted = 0;
      for (var _i = 0; _i < image.length; _i++) {
        var bgContainment = node.cy().style().getIndexedStyle(node, 'background-image-containment', 'value', _i);
        if (inside && bgContainment === 'over' || !inside && bgContainment === 'inside') {
          totalCompleted++;
          continue;
        }
        if (urlDefined[_i] && image[_i].complete && !image[_i].error) {
          totalCompleted++;
          r.drawInscribedImage(context, image[_i], node, _i, nodeOpacity);
        }
      }
      _p.backgrounding = !(totalCompleted === numImages);
      if (prevBging !== _p.backgrounding) {
        // update style b/c :backgrounding state changed
        node.updateStyle(false);
      }
    };
    var drawPie = function drawPie() {
      var redrawShape = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var pieOpacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : eleOpacity;
      if (r.hasPie(node)) {
        r.drawPie(context, node, pieOpacity);

        // redraw/restore path if steps after pie need it
        if (redrawShape) {
          if (!usePaths) {
            r.nodeShapes[r.getNodeShape(node)].draw(context, pos.x, pos.y, nodeWidth, nodeHeight);
          }
        }
      }
    };
    var darken = function darken() {
      var darkenOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;
      var opacity = (darkness > 0 ? darkness : -darkness) * darkenOpacity;
      var c = darkness > 0 ? 0 : 255;
      if (darkness !== 0) {
        r.colorFillStyle(context, c, c, c, opacity);
        if (usePaths) {
          context.fill(path);
        } else {
          context.fill();
        }
      }
    };
    var drawBorder = function drawBorder() {
      if (borderWidth > 0) {
        context.lineWidth = borderWidth;
        context.lineCap = 'butt';
        if (context.setLineDash) {
          // for very outofdate browsers
          switch (borderStyle) {
            case 'dotted':
              context.setLineDash([1, 1]);
              break;
            case 'dashed':
              context.setLineDash([4, 2]);
              break;
            case 'solid':
            case 'double':
              context.setLineDash([]);
              break;
          }
        }
        if (usePaths) {
          context.stroke(path);
        } else {
          context.stroke();
        }
        if (borderStyle === 'double') {
          context.lineWidth = borderWidth / 3;
          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';
          if (usePaths) {
            context.stroke(path);
          } else {
            context.stroke();
          }
          context.globalCompositeOperation = gco;
        }

        // reset in case we changed the border style
        if (context.setLineDash) {
          // for very outofdate browsers
          context.setLineDash([]);
        }
      }
    };
    var drawOutline = function drawOutline() {
      if (outlineWidth > 0) {
        context.lineWidth = outlineWidth;
        context.lineCap = 'butt';
        if (context.setLineDash) {
          // for very outofdate browsers
          switch (outlineStyle) {
            case 'dotted':
              context.setLineDash([1, 1]);
              break;
            case 'dashed':
              context.setLineDash([4, 2]);
              break;
            case 'solid':
            case 'double':
              context.setLineDash([]);
              break;
          }
        }
        var npos = pos;
        if (usePaths) {
          npos = {
            x: 0,
            y: 0
          };
        }
        var shape = r.getNodeShape(node);
        var scaleX = (nodeWidth + borderWidth + (outlineWidth + outlineOffset)) / nodeWidth;
        var scaleY = (nodeHeight + borderWidth + (outlineWidth + outlineOffset)) / nodeHeight;
        var sWidth = nodeWidth * scaleX;
        var sHeight = nodeHeight * scaleY;
        var points = r.nodeShapes[shape].points;
        var _path;
        if (usePaths) {
          var outlinePath = getPath(sWidth, sHeight, shape, points);
          _path = outlinePath.path;
        }

        // draw the outline path, either by using expanded points or by scaling 
        // the dimensions, depending on shape
        if (shape === "ellipse") {
          r.drawEllipsePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['round-diamond', 'round-heptagon', 'round-hexagon', 'round-octagon', 'round-pentagon', 'round-polygon', 'round-triangle', 'round-tag'].includes(shape)) {
          var sMult = 0;
          var offsetX = 0;
          var offsetY = 0;
          if (shape === 'round-diamond') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.4;
          } else if (shape === 'round-heptagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.075;
            offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 35;
          } else if (shape === 'round-hexagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12;
          } else if (shape === 'round-pentagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.13;
            offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 15;
          } else if (shape === 'round-tag') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12;
            offsetX = (borderWidth / 2 + outlineWidth + outlineOffset) * .07;
          } else if (shape === 'round-triangle') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * (Math.PI / 2);
            offsetY = -(borderWidth + outlineOffset / 2 + outlineWidth) / Math.PI;
          }
          if (sMult !== 0) {
            scaleX = (nodeWidth + sMult) / nodeWidth;
            scaleY = (nodeHeight + sMult) / nodeHeight;
          }
          r.drawRoundPolygonPath(_path || context, npos.x + offsetX, npos.y + offsetY, nodeWidth * scaleX, nodeHeight * scaleY, points);
        } else if (['roundrectangle', 'round-rectangle'].includes(shape)) {
          r.drawRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['cutrectangle', 'cut-rectangle'].includes(shape)) {
          r.drawCutRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['bottomroundrectangle', 'bottom-round-rectangle'].includes(shape)) {
          r.drawBottomRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (shape === "barrel") {
          r.drawBarrelPath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (shape.startsWith("polygon") || ['rhomboid', 'right-rhomboid', 'round-tag', 'tag', 'vee'].includes(shape)) {
          var pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth;
          points = joinLines(expandPolygon(points, pad));
          r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);
        } else {
          var _pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth;
          points = joinLines(expandPolygon(points, -_pad));
          r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);
        }
        if (usePaths) {
          context.stroke(_path);
        } else {
          context.stroke();
        }
        if (outlineStyle === 'double') {
          context.lineWidth = borderWidth / 3;
          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';
          if (usePaths) {
            context.stroke(_path);
          } else {
            context.stroke();
          }
          context.globalCompositeOperation = gco;
        }

        // reset in case we changed the border style
        if (context.setLineDash) {
          // for very outofdate browsers
          context.setLineDash([]);
        }
      }
    };
    var drawOverlay = function drawOverlay() {
      if (shouldDrawOverlay) {
        r.drawNodeOverlay(context, node, pos, nodeWidth, nodeHeight);
      }
    };
    var drawUnderlay = function drawUnderlay() {
      if (shouldDrawOverlay) {
        r.drawNodeUnderlay(context, node, pos, nodeWidth, nodeHeight);
      }
    };
    var drawText = function drawText() {
      r.drawElementText(context, node, null, drawLabel);
    };
    var ghost = node.pstyle('ghost').value === 'yes';
    if (ghost) {
      var gx = node.pstyle('ghost-offset-x').pfValue;
      var gy = node.pstyle('ghost-offset-y').pfValue;
      var ghostOpacity = node.pstyle('ghost-opacity').value;
      var effGhostOpacity = ghostOpacity * eleOpacity;
      context.translate(gx, gy);
      setupOutlineColor();
      drawOutline();
      setupShapeColor(ghostOpacity * bgOpacity);
      drawShape();
      drawImages(effGhostOpacity, true);
      setupBorderColor(ghostOpacity * borderOpacity);
      drawBorder();
      drawPie(darkness !== 0 || borderWidth !== 0);
      drawImages(effGhostOpacity, false);
      darken(effGhostOpacity);
      context.translate(-gx, -gy);
    }
    if (usePaths) {
      context.translate(-pos.x, -pos.y);
    }
    drawUnderlay();
    if (usePaths) {
      context.translate(pos.x, pos.y);
    }
    setupOutlineColor();
    drawOutline();
    setupShapeColor();
    drawShape();
    drawImages(eleOpacity, true);
    setupBorderColor();
    drawBorder();
    drawPie(darkness !== 0 || borderWidth !== 0);
    drawImages(eleOpacity, false);
    darken();
    if (usePaths) {
      context.translate(-pos.x, -pos.y);
    }
    drawText();
    drawOverlay();

    //
    // clean up shift

    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  var drawNodeOverlayUnderlay = function drawNodeOverlayUnderlay(overlayOrUnderlay) {
    if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {
      throw new Error('Invalid state');
    }
    return function (context, node, pos, nodeWidth, nodeHeight) {
      var r = this;
      if (!node.visible()) {
        return;
      }
      var padding = node.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue;
      var opacity = node.pstyle("".concat(overlayOrUnderlay, "-opacity")).value;
      var color = node.pstyle("".concat(overlayOrUnderlay, "-color")).value;
      var shape = node.pstyle("".concat(overlayOrUnderlay, "-shape")).value;
      if (opacity > 0) {
        pos = pos || node.position();
        if (nodeWidth == null || nodeHeight == null) {
          var _padding = node.padding();
          nodeWidth = node.width() + 2 * _padding;
          nodeHeight = node.height() + 2 * _padding;
        }
        r.colorFillStyle(context, color[0], color[1], color[2], opacity);
        r.nodeShapes[shape].draw(context, pos.x, pos.y, nodeWidth + padding * 2, nodeHeight + padding * 2);
        context.fill();
      }
    };
  };
  CRp$5.drawNodeOverlay = drawNodeOverlayUnderlay('overlay');
  CRp$5.drawNodeUnderlay = drawNodeOverlayUnderlay('underlay');

  // does the node have at least one pie piece?
  CRp$5.hasPie = function (node) {
    node = node[0]; // ensure ele ref

    return node._private.hasPie;
  };
  CRp$5.drawPie = function (context, node, nodeOpacity, pos) {
    node = node[0]; // ensure ele ref
    pos = pos || node.position();
    var cyStyle = node.cy().style();
    var pieSize = node.pstyle('pie-size');
    var x = pos.x;
    var y = pos.y;
    var nodeW = node.width();
    var nodeH = node.height();
    var radius = Math.min(nodeW, nodeH) / 2; // must fit in node
    var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]
    var usePaths = this.usePaths();
    if (usePaths) {
      x = 0;
      y = 0;
    }
    if (pieSize.units === '%') {
      radius = radius * pieSize.pfValue;
    } else if (pieSize.pfValue !== undefined) {
      radius = pieSize.pfValue / 2;
    }
    for (var i = 1; i <= cyStyle.pieBackgroundN; i++) {
      // 1..N
      var size = node.pstyle('pie-' + i + '-background-size').value;
      var color = node.pstyle('pie-' + i + '-background-color').value;
      var opacity = node.pstyle('pie-' + i + '-background-opacity').value * nodeOpacity;
      var percent = size / 100; // map integer range [0, 100] to [0, 1]

      // percent can't push beyond 1
      if (percent + lastPercent > 1) {
        percent = 1 - lastPercent;
      }
      var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise
      var angleDelta = 2 * Math.PI * percent;
      var angleEnd = angleStart + angleDelta;

      // ignore if
      // - zero size
      // - we're already beyond the full circle
      // - adding the current slice would go beyond the full circle
      if (size === 0 || lastPercent >= 1 || lastPercent + percent > 1) {
        continue;
      }
      context.beginPath();
      context.moveTo(x, y);
      context.arc(x, y, radius, angleStart, angleEnd);
      context.closePath();
      this.colorFillStyle(context, color[0], color[1], color[2], opacity);
      context.fill();
      lastPercent += percent;
    }
  };

  var CRp$4 = {};
  var motionBlurDelay = 100;

  // var isFirefox = typeof InstallTrigger !== 'undefined';

  CRp$4.getPixelRatio = function () {
    var context = this.data.contexts[0];
    if (this.forcedPixelRatio != null) {
      return this.forcedPixelRatio;
    }
    var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
    return (window.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef
  };

  CRp$4.paintCache = function (context) {
    var caches = this.paintCaches = this.paintCaches || [];
    var needToCreateCache = true;
    var cache;
    for (var i = 0; i < caches.length; i++) {
      cache = caches[i];
      if (cache.context === context) {
        needToCreateCache = false;
        break;
      }
    }
    if (needToCreateCache) {
      cache = {
        context: context
      };
      caches.push(cache);
    }
    return cache;
  };
  CRp$4.createGradientStyleFor = function (context, shapeStyleName, ele, fill, opacity) {
    var gradientStyle;
    var usePaths = this.usePaths();
    var colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value,
      positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue;
    if (fill === 'radial-gradient') {
      if (ele.isEdge()) {
        var start = ele.sourceEndpoint(),
          end = ele.targetEndpoint(),
          mid = ele.midpoint();
        var d1 = dist(start, mid);
        var d2 = dist(end, mid);
        gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2));
      } else {
        var pos = usePaths ? {
            x: 0,
            y: 0
          } : ele.position(),
          width = ele.paddedWidth(),
          height = ele.paddedHeight();
        gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height));
      }
    } else {
      if (ele.isEdge()) {
        var _start = ele.sourceEndpoint(),
          _end = ele.targetEndpoint();
        gradientStyle = context.createLinearGradient(_start.x, _start.y, _end.x, _end.y);
      } else {
        var _pos = usePaths ? {
            x: 0,
            y: 0
          } : ele.position(),
          _width = ele.paddedWidth(),
          _height = ele.paddedHeight(),
          halfWidth = _width / 2,
          halfHeight = _height / 2;
        var direction = ele.pstyle('background-gradient-direction').value;
        switch (direction) {
          case 'to-bottom':
            gradientStyle = context.createLinearGradient(_pos.x, _pos.y - halfHeight, _pos.x, _pos.y + halfHeight);
            break;
          case 'to-top':
            gradientStyle = context.createLinearGradient(_pos.x, _pos.y + halfHeight, _pos.x, _pos.y - halfHeight);
            break;
          case 'to-left':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y, _pos.x - halfWidth, _pos.y);
            break;
          case 'to-right':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y, _pos.x + halfWidth, _pos.y);
            break;
          case 'to-bottom-right':
          case 'to-right-bottom':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y - halfHeight, _pos.x + halfWidth, _pos.y + halfHeight);
            break;
          case 'to-top-right':
          case 'to-right-top':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y + halfHeight, _pos.x + halfWidth, _pos.y - halfHeight);
            break;
          case 'to-bottom-left':
          case 'to-left-bottom':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y - halfHeight, _pos.x - halfWidth, _pos.y + halfHeight);
            break;
          case 'to-top-left':
          case 'to-left-top':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y + halfHeight, _pos.x - halfWidth, _pos.y - halfHeight);
            break;
        }
      }
    }
    if (!gradientStyle) return null; // invalid gradient style

    var hasPositions = positions.length === colors.length;
    var length = colors.length;
    for (var i = 0; i < length; i++) {
      gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')');
    }
    return gradientStyle;
  };
  CRp$4.gradientFillStyle = function (context, ele, fill, opacity) {
    var gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity);
    if (!gradientStyle) return null; // error
    context.fillStyle = gradientStyle;
  };
  CRp$4.colorFillStyle = function (context, r, g, b, a) {
    context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    // turn off for now, seems context does its own caching

    // var cache = this.paintCache(context);

    // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

    // if( cache.fillStyle !== fillStyle ){
    //   context.fillStyle = cache.fillStyle = fillStyle;
    // }
  };

  CRp$4.eleFillStyle = function (context, ele, opacity) {
    var backgroundFill = ele.pstyle('background-fill').value;
    if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') {
      this.gradientFillStyle(context, ele, backgroundFill, opacity);
    } else {
      var backgroundColor = ele.pstyle('background-color').value;
      this.colorFillStyle(context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity);
    }
  };
  CRp$4.gradientStrokeStyle = function (context, ele, fill, opacity) {
    var gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill, opacity);
    if (!gradientStyle) return null; // error
    context.strokeStyle = gradientStyle;
  };
  CRp$4.colorStrokeStyle = function (context, r, g, b, a) {
    context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    // turn off for now, seems context does its own caching

    // var cache = this.paintCache(context);

    // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

    // if( cache.strokeStyle !== strokeStyle ){
    //   context.strokeStyle = cache.strokeStyle = strokeStyle;
    // }
  };

  CRp$4.eleStrokeStyle = function (context, ele, opacity) {
    var lineFill = ele.pstyle('line-fill').value;
    if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') {
      this.gradientStrokeStyle(context, ele, lineFill, opacity);
    } else {
      var lineColor = ele.pstyle('line-color').value;
      this.colorStrokeStyle(context, lineColor[0], lineColor[1], lineColor[2], opacity);
    }
  };

  // Resize canvas
  CRp$4.matchCanvasSize = function (container) {
    var r = this;
    var data = r.data;
    var bb = r.findContainerClientCoords();
    var width = bb[2];
    var height = bb[3];
    var pixelRatio = r.getPixelRatio();
    var mbPxRatio = r.motionBlurPxRatio;
    if (container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] || container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]) {
      pixelRatio = mbPxRatio;
    }
    var canvasWidth = width * pixelRatio;
    var canvasHeight = height * pixelRatio;
    var canvas;
    if (canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight) {
      return; // save cycles if same
    }

    r.fontCaches = null; // resizing resets the style

    var canvasContainer = data.canvasContainer;
    canvasContainer.style.width = width + 'px';
    canvasContainer.style.height = height + 'px';
    for (var i = 0; i < r.CANVAS_LAYERS; i++) {
      canvas = data.canvases[i];
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
    }
    for (var i = 0; i < r.BUFFER_COUNT; i++) {
      canvas = data.bufferCanvases[i];
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
    }
    r.textureMult = 1;
    if (pixelRatio <= 1) {
      canvas = data.bufferCanvases[r.TEXTURE_BUFFER];
      r.textureMult = 2;
      canvas.width = canvasWidth * r.textureMult;
      canvas.height = canvasHeight * r.textureMult;
    }
    r.canvasWidth = canvasWidth;
    r.canvasHeight = canvasHeight;
  };
  CRp$4.renderTo = function (cxt, zoom, pan, pxRatio) {
    this.render({
      forcedContext: cxt,
      forcedZoom: zoom,
      forcedPan: pan,
      drawAllLayers: true,
      forcedPxRatio: pxRatio
    });
  };
  CRp$4.render = function (options) {
    options = options || staticEmptyObject();
    var forcedContext = options.forcedContext;
    var drawAllLayers = options.drawAllLayers;
    var drawOnlyNodeLayer = options.drawOnlyNodeLayer;
    var forcedZoom = options.forcedZoom;
    var forcedPan = options.forcedPan;
    var r = this;
    var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;
    var cy = r.cy;
    var data = r.data;
    var needDraw = data.canvasNeedsRedraw;
    var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);
    var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;
    var mbPxRatio = r.motionBlurPxRatio;
    var hasCompoundNodes = cy.hasCompoundNodes();
    var inNodeDragGesture = r.hoverData.draggingEles;
    var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;
    motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;
    var motionBlurFadeEffect = motionBlur;
    if (!forcedContext) {
      if (r.prevPxRatio !== pixelRatio) {
        r.invalidateContainerClientCoordsCache();
        r.matchCanvasSize(r.container);
        r.redrawHint('eles', true);
        r.redrawHint('drag', true);
      }
      r.prevPxRatio = pixelRatio;
    }
    if (!forcedContext && r.motionBlurTimeout) {
      clearTimeout(r.motionBlurTimeout);
    }
    if (motionBlur) {
      if (r.mbFrames == null) {
        r.mbFrames = 0;
      }
      r.mbFrames++;
      if (r.mbFrames < 3) {
        // need several frames before even high quality motionblur
        motionBlurFadeEffect = false;
      }

      // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)
      if (r.mbFrames > r.minMbLowQualFrames) {
        //r.fullQualityMb = false;
        r.motionBlurPxRatio = r.mbPxRBlurry;
      }
    }
    if (r.clearingMotionBlur) {
      r.motionBlurPxRatio = 1;
    }

    // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame
    // because a rogue async texture frame would clear needDraw
    if (r.textureDrawLastFrame && !textureDraw) {
      needDraw[r.NODE] = true;
      needDraw[r.SELECT_BOX] = true;
    }
    var style = cy.style();
    var zoom = cy.zoom();
    var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;
    var pan = cy.pan();
    var effectivePan = {
      x: pan.x,
      y: pan.y
    };
    var vp = {
      zoom: zoom,
      pan: {
        x: pan.x,
        y: pan.y
      }
    };
    var prevVp = r.prevViewport;
    var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;

    // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)
    if (!viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes)) {
      r.motionBlurPxRatio = 1;
    }
    if (forcedPan) {
      effectivePan = forcedPan;
    }

    // apply pixel ratio

    effectiveZoom *= pixelRatio;
    effectivePan.x *= pixelRatio;
    effectivePan.y *= pixelRatio;
    var eles = r.getCachedZSortedEles();
    function mbclear(context, x, y, w, h) {
      var gco = context.globalCompositeOperation;
      context.globalCompositeOperation = 'destination-out';
      r.colorFillStyle(context, 255, 255, 255, r.motionBlurTransparency);
      context.fillRect(x, y, w, h);
      context.globalCompositeOperation = gco;
    }
    function setContextTransform(context, clear) {
      var ePan, eZoom, w, h;
      if (!r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG])) {
        ePan = {
          x: pan.x * mbPxRatio,
          y: pan.y * mbPxRatio
        };
        eZoom = zoom * mbPxRatio;
        w = r.canvasWidth * mbPxRatio;
        h = r.canvasHeight * mbPxRatio;
      } else {
        ePan = effectivePan;
        eZoom = effectiveZoom;
        w = r.canvasWidth;
        h = r.canvasHeight;
      }
      context.setTransform(1, 0, 0, 1, 0, 0);
      if (clear === 'motionBlur') {
        mbclear(context, 0, 0, w, h);
      } else if (!forcedContext && (clear === undefined || clear)) {
        context.clearRect(0, 0, w, h);
      }
      if (!drawAllLayers) {
        context.translate(ePan.x, ePan.y);
        context.scale(eZoom, eZoom);
      }
      if (forcedPan) {
        context.translate(forcedPan.x, forcedPan.y);
      }
      if (forcedZoom) {
        context.scale(forcedZoom, forcedZoom);
      }
    }
    if (!textureDraw) {
      r.textureDrawLastFrame = false;
    }
    if (textureDraw) {
      r.textureDrawLastFrame = true;
      if (!r.textureCache) {
        r.textureCache = {};
        r.textureCache.bb = cy.mutableElements().boundingBox();
        r.textureCache.texture = r.data.bufferCanvases[r.TEXTURE_BUFFER];
        var cxt = r.data.bufferContexts[r.TEXTURE_BUFFER];
        cxt.setTransform(1, 0, 0, 1, 0, 0);
        cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult);
        r.render({
          forcedContext: cxt,
          drawOnlyNodeLayer: true,
          forcedPxRatio: pixelRatio * r.textureMult
        });
        var vp = r.textureCache.viewport = {
          zoom: cy.zoom(),
          pan: cy.pan(),
          width: r.canvasWidth,
          height: r.canvasHeight
        };
        vp.mpan = {
          x: (0 - vp.pan.x) / vp.zoom,
          y: (0 - vp.pan.y) / vp.zoom
        };
      }
      needDraw[r.DRAG] = false;
      needDraw[r.NODE] = false;
      var context = data.contexts[r.NODE];
      var texture = r.textureCache.texture;
      var vp = r.textureCache.viewport;
      context.setTransform(1, 0, 0, 1, 0, 0);
      if (motionBlur) {
        mbclear(context, 0, 0, vp.width, vp.height);
      } else {
        context.clearRect(0, 0, vp.width, vp.height);
      }
      var outsideBgColor = style.core('outside-texture-bg-color').value;
      var outsideBgOpacity = style.core('outside-texture-bg-opacity').value;
      r.colorFillStyle(context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity);
      context.fillRect(0, 0, vp.width, vp.height);
      var zoom = cy.zoom();
      setContextTransform(context, false);
      context.clearRect(vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);
      context.drawImage(texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);
    } else if (r.textureOnViewport && !forcedContext) {
      // clear the cache since we don't need it
      r.textureCache = null;
    }
    var extent = cy.extent();
    var vpManip = r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated();
    var hideEdges = r.hideEdgesOnViewport && vpManip;
    var needMbClear = [];
    needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur;
    if (needMbClear[r.NODE]) {
      r.clearedForMotionBlur[r.NODE] = true;
    }
    needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur;
    if (needMbClear[r.DRAG]) {
      r.clearedForMotionBlur[r.DRAG] = true;
    }
    if (needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE]) {
      var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1;
      var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] : data.contexts[r.NODE]);
      var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;
      setContextTransform(context, clear);
      if (hideEdges) {
        r.drawCachedNodes(context, eles.nondrag, pixelRatio, extent);
      } else {
        r.drawLayeredElements(context, eles.nondrag, pixelRatio, extent);
      }
      if (r.debug) {
        r.drawDebugPoints(context, eles.nondrag);
      }
      if (!drawAllLayers && !motionBlur) {
        needDraw[r.NODE] = false;
      }
    }
    if (!drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG])) {
      var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1;
      var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG] : data.contexts[r.DRAG]);
      setContextTransform(context, motionBlur && !useBuffer ? 'motionBlur' : undefined);
      if (hideEdges) {
        r.drawCachedNodes(context, eles.drag, pixelRatio, extent);
      } else {
        r.drawCachedElements(context, eles.drag, pixelRatio, extent);
      }
      if (r.debug) {
        r.drawDebugPoints(context, eles.drag);
      }
      if (!drawAllLayers && !motionBlur) {
        needDraw[r.DRAG] = false;
      }
    }
    if (r.showFps || !drawOnlyNodeLayer && needDraw[r.SELECT_BOX] && !drawAllLayers) {
      var context = forcedContext || data.contexts[r.SELECT_BOX];
      setContextTransform(context);
      if (r.selection[4] == 1 && (r.hoverData.selecting || r.touchData.selecting)) {
        var zoom = r.cy.zoom();
        var borderWidth = style.core('selection-box-border-width').value / zoom;
        context.lineWidth = borderWidth;
        context.fillStyle = 'rgba(' + style.core('selection-box-color').value[0] + ',' + style.core('selection-box-color').value[1] + ',' + style.core('selection-box-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';
        context.fillRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);
        if (borderWidth > 0) {
          context.strokeStyle = 'rgba(' + style.core('selection-box-border-color').value[0] + ',' + style.core('selection-box-border-color').value[1] + ',' + style.core('selection-box-border-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';
          context.strokeRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);
        }
      }
      if (data.bgActivePosistion && !r.hoverData.selecting) {
        var zoom = r.cy.zoom();
        var pos = data.bgActivePosistion;
        context.fillStyle = 'rgba(' + style.core('active-bg-color').value[0] + ',' + style.core('active-bg-color').value[1] + ',' + style.core('active-bg-color').value[2] + ',' + style.core('active-bg-opacity').value + ')';
        context.beginPath();
        context.arc(pos.x, pos.y, style.core('active-bg-size').pfValue / zoom, 0, 2 * Math.PI);
        context.fill();
      }
      var timeToRender = r.lastRedrawTime;
      if (r.showFps && timeToRender) {
        timeToRender = Math.round(timeToRender);
        var fps = Math.round(1000 / timeToRender);
        context.setTransform(1, 0, 0, 1, 0, 0);
        context.fillStyle = 'rgba(255, 0, 0, 0.75)';
        context.strokeStyle = 'rgba(255, 0, 0, 0.75)';
        context.lineWidth = 1;
        context.fillText('1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20);
        var maxFps = 60;
        context.strokeRect(0, 30, 250, 20);
        context.fillRect(0, 30, 250 * Math.min(fps / maxFps, 1), 20);
      }
      if (!drawAllLayers) {
        needDraw[r.SELECT_BOX] = false;
      }
    }

    // motionblur: blit rendered blurry frames
    if (motionBlur && mbPxRatio !== 1) {
      var cxtNode = data.contexts[r.NODE];
      var txtNode = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE];
      var cxtDrag = data.contexts[r.DRAG];
      var txtDrag = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG];
      var drawMotionBlur = function drawMotionBlur(cxt, txt, needClear) {
        cxt.setTransform(1, 0, 0, 1, 0, 0);
        if (needClear || !motionBlurFadeEffect) {
          cxt.clearRect(0, 0, r.canvasWidth, r.canvasHeight);
        } else {
          mbclear(cxt, 0, 0, r.canvasWidth, r.canvasHeight);
        }
        var pxr = mbPxRatio;
        cxt.drawImage(txt,
        // img
        0, 0,
        // sx, sy
        r.canvasWidth * pxr, r.canvasHeight * pxr,
        // sw, sh
        0, 0,
        // x, y
        r.canvasWidth, r.canvasHeight // w, h
        );
      };

      if (needDraw[r.NODE] || needMbClear[r.NODE]) {
        drawMotionBlur(cxtNode, txtNode, needMbClear[r.NODE]);
        needDraw[r.NODE] = false;
      }
      if (needDraw[r.DRAG] || needMbClear[r.DRAG]) {
        drawMotionBlur(cxtDrag, txtDrag, needMbClear[r.DRAG]);
        needDraw[r.DRAG] = false;
      }
    }
    r.prevViewport = vp;
    if (r.clearingMotionBlur) {
      r.clearingMotionBlur = false;
      r.motionBlurCleared = true;
      r.motionBlur = true;
    }
    if (motionBlur) {
      r.motionBlurTimeout = setTimeout(function () {
        r.motionBlurTimeout = null;
        r.clearedForMotionBlur[r.NODE] = false;
        r.clearedForMotionBlur[r.DRAG] = false;
        r.motionBlur = false;
        r.clearingMotionBlur = !textureDraw;
        r.mbFrames = 0;
        needDraw[r.NODE] = true;
        needDraw[r.DRAG] = true;
        r.redraw();
      }, motionBlurDelay);
    }
    if (!forcedContext) {
      cy.emit('render');
    }
  };

  var CRp$3 = {};

  // @O Polygon drawing
  CRp$3.drawPolygonPath = function (context, x, y, width, height, points) {
    var halfW = width / 2;
    var halfH = height / 2;
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(x + halfW * points[0], y + halfH * points[1]);
    for (var i = 1; i < points.length / 2; i++) {
      context.lineTo(x + halfW * points[i * 2], y + halfH * points[i * 2 + 1]);
    }
    context.closePath();
  };
  CRp$3.drawRoundPolygonPath = function (context, x, y, width, height, points) {
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }
    for (var _i = 0; _i < points.length / 4; _i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (_i === 0) {
        sourceUv = points.length - 2;
      } else {
        sourceUv = _i * 4 - 2;
      }
      destUv = _i * 4 + 2;
      var px = x + halfW * points[_i * 4];
      var py = y + halfH * points[_i * 4 + 1];
      var cosTheta = -points[sourceUv] * points[destUv] - points[sourceUv + 1] * points[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * points[sourceUv];
      var cp0y = py - offset * points[sourceUv + 1];
      var cp1x = px + offset * points[destUv];
      var cp1y = py + offset * points[destUv + 1];
      if (_i === 0) {
        context.moveTo(cp0x, cp0y);
      } else {
        context.lineTo(cp0x, cp0y);
      }
      context.arcTo(px, py, cp1x, cp1y, cornerRadius);
    }
    context.closePath();
  };

  // Round rectangle drawing
  CRp$3.drawRoundRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerRadius = getRoundRectangleRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }

    // Start at top middle
    context.moveTo(x, y - halfHeight);
    // Arc from middle top to right side
    context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius);
    // Arc from right side to bottom
    context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);
    // Arc from bottom to left side
    context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);
    // Arc from left side to topBorder
    context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius);
    // Join line
    context.lineTo(x, y - halfHeight);
    context.closePath();
  };
  CRp$3.drawBottomRoundRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerRadius = getRoundRectangleRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }

    // Start at top middle
    context.moveTo(x, y - halfHeight);
    context.lineTo(x + halfWidth, y - halfHeight);
    context.lineTo(x + halfWidth, y);
    context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);
    context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);
    context.lineTo(x - halfWidth, y - halfHeight);
    context.lineTo(x, y - halfHeight);
    context.closePath();
  };
  CRp$3.drawCutRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerLength = getCutRectangleCornerLength();
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(x - halfWidth + cornerLength, y - halfHeight);
    context.lineTo(x + halfWidth - cornerLength, y - halfHeight);
    context.lineTo(x + halfWidth, y - halfHeight + cornerLength);
    context.lineTo(x + halfWidth, y + halfHeight - cornerLength);
    context.lineTo(x + halfWidth - cornerLength, y + halfHeight);
    context.lineTo(x - halfWidth + cornerLength, y + halfHeight);
    context.lineTo(x - halfWidth, y + halfHeight - cornerLength);
    context.lineTo(x - halfWidth, y - halfHeight + cornerLength);
    context.closePath();
  };
  CRp$3.drawBarrelPath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var xBegin = x - halfWidth;
    var xEnd = x + halfWidth;
    var yBegin = y - halfHeight;
    var yEnd = y + halfHeight;
    var barrelCurveConstants = getBarrelCurveConstants(width, height);
    var wOffset = barrelCurveConstants.widthOffset;
    var hOffset = barrelCurveConstants.heightOffset;
    var ctrlPtXOffset = barrelCurveConstants.ctrlPtOffsetPct * wOffset;
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(xBegin, yBegin + hOffset);
    context.lineTo(xBegin, yEnd - hOffset);
    context.quadraticCurveTo(xBegin + ctrlPtXOffset, yEnd, xBegin + wOffset, yEnd);
    context.lineTo(xEnd - wOffset, yEnd);
    context.quadraticCurveTo(xEnd - ctrlPtXOffset, yEnd, xEnd, yEnd - hOffset);
    context.lineTo(xEnd, yBegin + hOffset);
    context.quadraticCurveTo(xEnd - ctrlPtXOffset, yBegin, xEnd - wOffset, yBegin);
    context.lineTo(xBegin + wOffset, yBegin);
    context.quadraticCurveTo(xBegin + ctrlPtXOffset, yBegin, xBegin, yBegin + hOffset);
    context.closePath();
  };
  var sin0 = Math.sin(0);
  var cos0 = Math.cos(0);
  var sin = {};
  var cos = {};
  var ellipseStepSize = Math.PI / 40;
  for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {
    sin[i] = Math.sin(i);
    cos[i] = Math.cos(i);
  }
  CRp$3.drawEllipsePath = function (context, centerX, centerY, width, height) {
    if (context.beginPath) {
      context.beginPath();
    }
    if (context.ellipse) {
      context.ellipse(centerX, centerY, width / 2, height / 2, 0, 0, 2 * Math.PI);
    } else {
      var xPos, yPos;
      var rw = width / 2;
      var rh = height / 2;
      for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {
        xPos = centerX - rw * sin[i] * sin0 + rw * cos[i] * cos0;
        yPos = centerY + rh * cos[i] * sin0 + rh * sin[i] * cos0;
        if (i === 0) {
          context.moveTo(xPos, yPos);
        } else {
          context.lineTo(xPos, yPos);
        }
      }
    }
    context.closePath();
  };

  /* global atob, ArrayBuffer, Uint8Array, Blob */
  var CRp$2 = {};
  CRp$2.createBuffer = function (w, h) {
    var buffer = document.createElement('canvas'); // eslint-disable-line no-undef
    buffer.width = w;
    buffer.height = h;
    return [buffer, buffer.getContext('2d')];
  };
  CRp$2.bufferCanvasImage = function (options) {
    var cy = this.cy;
    var eles = cy.mutableElements();
    var bb = eles.boundingBox();
    var ctrRect = this.findContainerClientCoords();
    var width = options.full ? Math.ceil(bb.w) : ctrRect[2];
    var height = options.full ? Math.ceil(bb.h) : ctrRect[3];
    var specdMaxDims = number$1(options.maxWidth) || number$1(options.maxHeight);
    var pxRatio = this.getPixelRatio();
    var scale = 1;
    if (options.scale !== undefined) {
      width *= options.scale;
      height *= options.scale;
      scale = options.scale;
    } else if (specdMaxDims) {
      var maxScaleW = Infinity;
      var maxScaleH = Infinity;
      if (number$1(options.maxWidth)) {
        maxScaleW = scale * options.maxWidth / width;
      }
      if (number$1(options.maxHeight)) {
        maxScaleH = scale * options.maxHeight / height;
      }
      scale = Math.min(maxScaleW, maxScaleH);
      width *= scale;
      height *= scale;
    }
    if (!specdMaxDims) {
      width *= pxRatio;
      height *= pxRatio;
      scale *= pxRatio;
    }
    var buffCanvas = document.createElement('canvas'); // eslint-disable-line no-undef

    buffCanvas.width = width;
    buffCanvas.height = height;
    buffCanvas.style.width = width + 'px';
    buffCanvas.style.height = height + 'px';
    var buffCxt = buffCanvas.getContext('2d');

    // Rasterize the layers, but only if container has nonzero size
    if (width > 0 && height > 0) {
      buffCxt.clearRect(0, 0, width, height);
      buffCxt.globalCompositeOperation = 'source-over';
      var zsortedEles = this.getCachedZSortedEles();
      if (options.full) {
        // draw the full bounds of the graph
        buffCxt.translate(-bb.x1 * scale, -bb.y1 * scale);
        buffCxt.scale(scale, scale);
        this.drawElements(buffCxt, zsortedEles);
        buffCxt.scale(1 / scale, 1 / scale);
        buffCxt.translate(bb.x1 * scale, bb.y1 * scale);
      } else {
        // draw the current view
        var pan = cy.pan();
        var translation = {
          x: pan.x * scale,
          y: pan.y * scale
        };
        scale *= cy.zoom();
        buffCxt.translate(translation.x, translation.y);
        buffCxt.scale(scale, scale);
        this.drawElements(buffCxt, zsortedEles);
        buffCxt.scale(1 / scale, 1 / scale);
        buffCxt.translate(-translation.x, -translation.y);
      }

      // need to fill bg at end like this in order to fill cleared transparent pixels in jpgs
      if (options.bg) {
        buffCxt.globalCompositeOperation = 'destination-over';
        buffCxt.fillStyle = options.bg;
        buffCxt.rect(0, 0, width, height);
        buffCxt.fill();
      }
    }
    return buffCanvas;
  };
  function b64ToBlob(b64, mimeType) {
    var bytes = atob(b64);
    var buff = new ArrayBuffer(bytes.length);
    var buffUint8 = new Uint8Array(buff);
    for (var i = 0; i < bytes.length; i++) {
      buffUint8[i] = bytes.charCodeAt(i);
    }
    return new Blob([buff], {
      type: mimeType
    });
  }
  function b64UriToB64(b64uri) {
    var i = b64uri.indexOf(',');
    return b64uri.substr(i + 1);
  }
  function output(options, canvas, mimeType) {
    var getB64Uri = function getB64Uri() {
      return canvas.toDataURL(mimeType, options.quality);
    };
    switch (options.output) {
      case 'blob-promise':
        return new Promise$1(function (resolve, reject) {
          try {
            canvas.toBlob(function (blob) {
              if (blob != null) {
                resolve(blob);
              } else {
                reject(new Error('`canvas.toBlob()` sent a null value in its callback'));
              }
            }, mimeType, options.quality);
          } catch (err) {
            reject(err);
          }
        });
      case 'blob':
        return b64ToBlob(b64UriToB64(getB64Uri()), mimeType);
      case 'base64':
        return b64UriToB64(getB64Uri());
      case 'base64uri':
      default:
        return getB64Uri();
    }
  }
  CRp$2.png = function (options) {
    return output(options, this.bufferCanvasImage(options), 'image/png');
  };
  CRp$2.jpg = function (options) {
    return output(options, this.bufferCanvasImage(options), 'image/jpeg');
  };

  var CRp$1 = {};
  CRp$1.nodeShapeImpl = function (name, context, centerX, centerY, width, height, points) {
    switch (name) {
      case 'ellipse':
        return this.drawEllipsePath(context, centerX, centerY, width, height);
      case 'polygon':
        return this.drawPolygonPath(context, centerX, centerY, width, height, points);
      case 'round-polygon':
        return this.drawRoundPolygonPath(context, centerX, centerY, width, height, points);
      case 'roundrectangle':
      case 'round-rectangle':
        return this.drawRoundRectanglePath(context, centerX, centerY, width, height);
      case 'cutrectangle':
      case 'cut-rectangle':
        return this.drawCutRectanglePath(context, centerX, centerY, width, height);
      case 'bottomroundrectangle':
      case 'bottom-round-rectangle':
        return this.drawBottomRoundRectanglePath(context, centerX, centerY, width, height);
      case 'barrel':
        return this.drawBarrelPath(context, centerX, centerY, width, height);
    }
  };

  var CR = CanvasRenderer;
  var CRp = CanvasRenderer.prototype;
  CRp.CANVAS_LAYERS = 3;
  //
  CRp.SELECT_BOX = 0;
  CRp.DRAG = 1;
  CRp.NODE = 2;
  CRp.BUFFER_COUNT = 3;
  //
  CRp.TEXTURE_BUFFER = 0;
  CRp.MOTIONBLUR_BUFFER_NODE = 1;
  CRp.MOTIONBLUR_BUFFER_DRAG = 2;
  function CanvasRenderer(options) {
    var r = this;
    r.data = {
      canvases: new Array(CRp.CANVAS_LAYERS),
      contexts: new Array(CRp.CANVAS_LAYERS),
      canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS),
      bufferCanvases: new Array(CRp.BUFFER_COUNT),
      bufferContexts: new Array(CRp.CANVAS_LAYERS)
    };
    var tapHlOffAttr = '-webkit-tap-highlight-color';
    var tapHlOffStyle = 'rgba(0,0,0,0)';
    r.data.canvasContainer = document.createElement('div'); // eslint-disable-line no-undef
    var containerStyle = r.data.canvasContainer.style;
    r.data.canvasContainer.style[tapHlOffAttr] = tapHlOffStyle;
    containerStyle.position = 'relative';
    containerStyle.zIndex = '0';
    containerStyle.overflow = 'hidden';
    var container = options.cy.container();
    container.appendChild(r.data.canvasContainer);
    container.style[tapHlOffAttr] = tapHlOffStyle;
    var styleMap = {
      '-webkit-user-select': 'none',
      '-moz-user-select': '-moz-none',
      'user-select': 'none',
      '-webkit-tap-highlight-color': 'rgba(0,0,0,0)',
      'outline-style': 'none'
    };
    if (ms()) {
      styleMap['-ms-touch-action'] = 'none';
      styleMap['touch-action'] = 'none';
    }
    for (var i = 0; i < CRp.CANVAS_LAYERS; i++) {
      var canvas = r.data.canvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef
      r.data.contexts[i] = canvas.getContext('2d');
      Object.keys(styleMap).forEach(function (k) {
        canvas.style[k] = styleMap[k];
      });
      canvas.style.position = 'absolute';
      canvas.setAttribute('data-id', 'layer' + i);
      canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i);
      r.data.canvasContainer.appendChild(canvas);
      r.data.canvasNeedsRedraw[i] = false;
    }
    r.data.topCanvas = r.data.canvases[0];
    r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node');
    r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox');
    r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag');
    for (var i = 0; i < CRp.BUFFER_COUNT; i++) {
      r.data.bufferCanvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef
      r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d');
      r.data.bufferCanvases[i].style.position = 'absolute';
      r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i);
      r.data.bufferCanvases[i].style.zIndex = String(-i - 1);
      r.data.bufferCanvases[i].style.visibility = 'hidden';
      //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]);
    }

    r.pathsEnabled = true;
    var emptyBb = makeBoundingBox();
    var getBoxCenter = function getBoxCenter(bb) {
      return {
        x: (bb.x1 + bb.x2) / 2,
        y: (bb.y1 + bb.y2) / 2
      };
    };
    var getCenterOffset = function getCenterOffset(bb) {
      return {
        x: -bb.w / 2,
        y: -bb.h / 2
      };
    };
    var backgroundTimestampHasChanged = function backgroundTimestampHasChanged(ele) {
      var _p = ele[0]._private;
      var same = _p.oldBackgroundTimestamp === _p.backgroundTimestamp;
      return !same;
    };
    var getStyleKey = function getStyleKey(ele) {
      return ele[0]._private.nodeKey;
    };
    var getLabelKey = function getLabelKey(ele) {
      return ele[0]._private.labelStyleKey;
    };
    var getSourceLabelKey = function getSourceLabelKey(ele) {
      return ele[0]._private.sourceLabelStyleKey;
    };
    var getTargetLabelKey = function getTargetLabelKey(ele) {
      return ele[0]._private.targetLabelStyleKey;
    };
    var drawElement = function drawElement(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElement(context, ele, bb, false, false, useEleOpacity);
    };
    var drawLabel = function drawLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'main', useEleOpacity);
    };
    var drawSourceLabel = function drawSourceLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'source', useEleOpacity);
    };
    var drawTargetLabel = function drawTargetLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'target', useEleOpacity);
    };
    var getElementBox = function getElementBox(ele) {
      ele.boundingBox();
      return ele[0]._private.bodyBounds;
    };
    var getLabelBox = function getLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.main || emptyBb;
    };
    var getSourceLabelBox = function getSourceLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.source || emptyBb;
    };
    var getTargetLabelBox = function getTargetLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.target || emptyBb;
    };
    var isLabelVisibleAtScale = function isLabelVisibleAtScale(ele, scaledLabelShown) {
      return scaledLabelShown;
    };
    var getElementRotationPoint = function getElementRotationPoint(ele) {
      return getBoxCenter(getElementBox(ele));
    };
    var addTextMargin = function addTextMargin(prefix, pt, ele) {
      var pre = prefix ? prefix + '-' : '';
      return {
        x: pt.x + ele.pstyle(pre + 'text-margin-x').pfValue,
        y: pt.y + ele.pstyle(pre + 'text-margin-y').pfValue
      };
    };
    var getRsPt = function getRsPt(ele, x, y) {
      var rs = ele[0]._private.rscratch;
      return {
        x: rs[x],
        y: rs[y]
      };
    };
    var getLabelRotationPoint = function getLabelRotationPoint(ele) {
      return addTextMargin('', getRsPt(ele, 'labelX', 'labelY'), ele);
    };
    var getSourceLabelRotationPoint = function getSourceLabelRotationPoint(ele) {
      return addTextMargin('source', getRsPt(ele, 'sourceLabelX', 'sourceLabelY'), ele);
    };
    var getTargetLabelRotationPoint = function getTargetLabelRotationPoint(ele) {
      return addTextMargin('target', getRsPt(ele, 'targetLabelX', 'targetLabelY'), ele);
    };
    var getElementRotationOffset = function getElementRotationOffset(ele) {
      return getCenterOffset(getElementBox(ele));
    };
    var getSourceLabelRotationOffset = function getSourceLabelRotationOffset(ele) {
      return getCenterOffset(getSourceLabelBox(ele));
    };
    var getTargetLabelRotationOffset = function getTargetLabelRotationOffset(ele) {
      return getCenterOffset(getTargetLabelBox(ele));
    };
    var getLabelRotationOffset = function getLabelRotationOffset(ele) {
      var bb = getLabelBox(ele);
      var p = getCenterOffset(getLabelBox(ele));
      if (ele.isNode()) {
        switch (ele.pstyle('text-halign').value) {
          case 'left':
            p.x = -bb.w;
            break;
          case 'right':
            p.x = 0;
            break;
        }
        switch (ele.pstyle('text-valign').value) {
          case 'top':
            p.y = -bb.h;
            break;
          case 'bottom':
            p.y = 0;
            break;
        }
      }
      return p;
    };
    var eleTxrCache = r.data.eleTxrCache = new ElementTextureCache(r, {
      getKey: getStyleKey,
      doesEleInvalidateKey: backgroundTimestampHasChanged,
      drawElement: drawElement,
      getBoundingBox: getElementBox,
      getRotationPoint: getElementRotationPoint,
      getRotationOffset: getElementRotationOffset,
      allowEdgeTxrCaching: false,
      allowParentTxrCaching: false
    });
    var lblTxrCache = r.data.lblTxrCache = new ElementTextureCache(r, {
      getKey: getLabelKey,
      drawElement: drawLabel,
      getBoundingBox: getLabelBox,
      getRotationPoint: getLabelRotationPoint,
      getRotationOffset: getLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var slbTxrCache = r.data.slbTxrCache = new ElementTextureCache(r, {
      getKey: getSourceLabelKey,
      drawElement: drawSourceLabel,
      getBoundingBox: getSourceLabelBox,
      getRotationPoint: getSourceLabelRotationPoint,
      getRotationOffset: getSourceLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var tlbTxrCache = r.data.tlbTxrCache = new ElementTextureCache(r, {
      getKey: getTargetLabelKey,
      drawElement: drawTargetLabel,
      getBoundingBox: getTargetLabelBox,
      getRotationPoint: getTargetLabelRotationPoint,
      getRotationOffset: getTargetLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var lyrTxrCache = r.data.lyrTxrCache = new LayeredTextureCache(r);
    r.onUpdateEleCalcs(function invalidateTextureCaches(willDraw, eles) {
      // each cache should check for sub-key diff to see that the update affects that cache particularly
      eleTxrCache.invalidateElements(eles);
      lblTxrCache.invalidateElements(eles);
      slbTxrCache.invalidateElements(eles);
      tlbTxrCache.invalidateElements(eles);

      // any change invalidates the layers
      lyrTxrCache.invalidateElements(eles);

      // update the old bg timestamp so diffs can be done in the ele txr caches
      for (var _i = 0; _i < eles.length; _i++) {
        var _p = eles[_i]._private;
        _p.oldBackgroundTimestamp = _p.backgroundTimestamp;
      }
    });
    var refineInLayers = function refineInLayers(reqs) {
      for (var i = 0; i < reqs.length; i++) {
        lyrTxrCache.enqueueElementRefinement(reqs[i].ele);
      }
    };
    eleTxrCache.onDequeue(refineInLayers);
    lblTxrCache.onDequeue(refineInLayers);
    slbTxrCache.onDequeue(refineInLayers);
    tlbTxrCache.onDequeue(refineInLayers);
  }
  CRp.redrawHint = function (group, bool) {
    var r = this;
    switch (group) {
      case 'eles':
        r.data.canvasNeedsRedraw[CRp.NODE] = bool;
        break;
      case 'drag':
        r.data.canvasNeedsRedraw[CRp.DRAG] = bool;
        break;
      case 'select':
        r.data.canvasNeedsRedraw[CRp.SELECT_BOX] = bool;
        break;
    }
  };

  // whether to use Path2D caching for drawing
  var pathsImpld = typeof Path2D !== 'undefined';
  CRp.path2dEnabled = function (on) {
    if (on === undefined) {
      return this.pathsEnabled;
    }
    this.pathsEnabled = on ? true : false;
  };
  CRp.usePaths = function () {
    return pathsImpld && this.pathsEnabled;
  };
  CRp.setImgSmoothing = function (context, bool) {
    if (context.imageSmoothingEnabled != null) {
      context.imageSmoothingEnabled = bool;
    } else {
      context.webkitImageSmoothingEnabled = bool;
      context.mozImageSmoothingEnabled = bool;
      context.msImageSmoothingEnabled = bool;
    }
  };
  CRp.getImgSmoothing = function (context) {
    if (context.imageSmoothingEnabled != null) {
      return context.imageSmoothingEnabled;
    } else {
      return context.webkitImageSmoothingEnabled || context.mozImageSmoothingEnabled || context.msImageSmoothingEnabled;
    }
  };
  CRp.makeOffscreenCanvas = function (width, height) {
    var canvas;
    if ((typeof OffscreenCanvas === "undefined" ? "undefined" : _typeof(OffscreenCanvas)) !== ("undefined" )) {
      canvas = new OffscreenCanvas(width, height);
    } else {
      canvas = document.createElement('canvas'); // eslint-disable-line no-undef
      canvas.width = width;
      canvas.height = height;
    }
    return canvas;
  };
  [CRp$a, CRp$9, CRp$8, CRp$7, CRp$6, CRp$5, CRp$4, CRp$3, CRp$2, CRp$1].forEach(function (props) {
    extend(CRp, props);
  });

  var renderer = [{
    name: 'null',
    impl: NullRenderer
  }, {
    name: 'base',
    impl: BR
  }, {
    name: 'canvas',
    impl: CR
  }];

  var incExts = [{
    type: 'layout',
    extensions: layout
  }, {
    type: 'renderer',
    extensions: renderer
  }];

  // registered extensions to cytoscape, indexed by name
  var extensions = {};

  // registered modules for extensions, indexed by name
  var modules = {};
  function setExtension(type, name, registrant) {
    var ext = registrant;
    var overrideErr = function overrideErr(field) {
      warn('Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden');
    };
    if (type === 'core') {
      if (Core.prototype[name]) {
        return overrideErr(name);
      } else {
        Core.prototype[name] = registrant;
      }
    } else if (type === 'collection') {
      if (Collection.prototype[name]) {
        return overrideErr(name);
      } else {
        Collection.prototype[name] = registrant;
      }
    } else if (type === 'layout') {
      // fill in missing layout functions in the prototype

      var Layout = function Layout(options) {
        this.options = options;
        registrant.call(this, options);

        // make sure layout has _private for use w/ std apis like .on()
        if (!plainObject(this._private)) {
          this._private = {};
        }
        this._private.cy = options.cy;
        this._private.listeners = [];
        this.createEmitter();
      };
      var layoutProto = Layout.prototype = Object.create(registrant.prototype);
      var optLayoutFns = [];
      for (var i = 0; i < optLayoutFns.length; i++) {
        var fnName = optLayoutFns[i];
        layoutProto[fnName] = layoutProto[fnName] || function () {
          return this;
        };
      }

      // either .start() or .run() is defined, so autogen the other
      if (layoutProto.start && !layoutProto.run) {
        layoutProto.run = function () {
          this.start();
          return this;
        };
      } else if (!layoutProto.start && layoutProto.run) {
        layoutProto.start = function () {
          this.run();
          return this;
        };
      }
      var regStop = registrant.prototype.stop;
      layoutProto.stop = function () {
        var opts = this.options;
        if (opts && opts.animate) {
          var anis = this.animations;
          if (anis) {
            for (var _i = 0; _i < anis.length; _i++) {
              anis[_i].stop();
            }
          }
        }
        if (regStop) {
          regStop.call(this);
        } else {
          this.emit('layoutstop');
        }
        return this;
      };
      if (!layoutProto.destroy) {
        layoutProto.destroy = function () {
          return this;
        };
      }
      layoutProto.cy = function () {
        return this._private.cy;
      };
      var getCy = function getCy(layout) {
        return layout._private.cy;
      };
      var emitterOpts = {
        addEventFields: function addEventFields(layout, evt) {
          evt.layout = layout;
          evt.cy = getCy(layout);
          evt.target = layout;
        },
        bubble: function bubble() {
          return true;
        },
        parent: function parent(layout) {
          return getCy(layout);
        }
      };
      extend(layoutProto, {
        createEmitter: function createEmitter() {
          this._private.emitter = new Emitter(emitterOpts, this);
          return this;
        },
        emitter: function emitter() {
          return this._private.emitter;
        },
        on: function on(evt, cb) {
          this.emitter().on(evt, cb);
          return this;
        },
        one: function one(evt, cb) {
          this.emitter().one(evt, cb);
          return this;
        },
        once: function once(evt, cb) {
          this.emitter().one(evt, cb);
          return this;
        },
        removeListener: function removeListener(evt, cb) {
          this.emitter().removeListener(evt, cb);
          return this;
        },
        removeAllListeners: function removeAllListeners() {
          this.emitter().removeAllListeners();
          return this;
        },
        emit: function emit(evt, params) {
          this.emitter().emit(evt, params);
          return this;
        }
      });
      define.eventAliasesOn(layoutProto);
      ext = Layout; // replace with our wrapped layout
    } else if (type === 'renderer' && name !== 'null' && name !== 'base') {
      // user registered renderers inherit from base

      var BaseRenderer = getExtension('renderer', 'base');
      var bProto = BaseRenderer.prototype;
      var RegistrantRenderer = registrant;
      var rProto = registrant.prototype;
      var Renderer = function Renderer() {
        BaseRenderer.apply(this, arguments);
        RegistrantRenderer.apply(this, arguments);
      };
      var proto = Renderer.prototype;
      for (var pName in bProto) {
        var pVal = bProto[pName];
        var existsInR = rProto[pName] != null;
        if (existsInR) {
          return overrideErr(pName);
        }
        proto[pName] = pVal; // take impl from base
      }

      for (var _pName in rProto) {
        proto[_pName] = rProto[_pName]; // take impl from registrant
      }

      bProto.clientFunctions.forEach(function (name) {
        proto[name] = proto[name] || function () {
          error('Renderer does not implement `renderer.' + name + '()` on its prototype');
        };
      });
      ext = Renderer;
    } else if (type === '__proto__' || type === 'constructor' || type === 'prototype') {
      // to avoid potential prototype pollution
      return error(type + ' is an illegal type to be registered, possibly lead to prototype pollutions');
    }
    return setMap({
      map: extensions,
      keys: [type, name],
      value: ext
    });
  }
  function getExtension(type, name) {
    return getMap({
      map: extensions,
      keys: [type, name]
    });
  }
  function setModule(type, name, moduleType, moduleName, registrant) {
    return setMap({
      map: modules,
      keys: [type, name, moduleType, moduleName],
      value: registrant
    });
  }
  function getModule(type, name, moduleType, moduleName) {
    return getMap({
      map: modules,
      keys: [type, name, moduleType, moduleName]
    });
  }
  var extension = function extension() {
    // e.g. extension('renderer', 'svg')
    if (arguments.length === 2) {
      return getExtension.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', { ... })
    else if (arguments.length === 3) {
      return setExtension.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')
    else if (arguments.length === 4) {
      return getModule.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })
    else if (arguments.length === 5) {
      return setModule.apply(null, arguments);
    } else {
      error('Invalid extension access syntax');
    }
  };

  // allows a core instance to access extensions internally
  Core.prototype.extension = extension;

  // included extensions
  incExts.forEach(function (group) {
    group.extensions.forEach(function (ext) {
      setExtension(group.type, ext.name, ext.impl);
    });
  });

  // a dummy stylesheet object that doesn't need a reference to the core
  // (useful for init)
  var Stylesheet = function Stylesheet() {
    if (!(this instanceof Stylesheet)) {
      return new Stylesheet();
    }
    this.length = 0;
  };
  var sheetfn = Stylesheet.prototype;
  sheetfn.instanceString = function () {
    return 'stylesheet';
  };

  // just store the selector to be parsed later
  sheetfn.selector = function (selector) {
    var i = this.length++;
    this[i] = {
      selector: selector,
      properties: []
    };
    return this; // chaining
  };

  // just store the property to be parsed later
  sheetfn.css = function (name, value) {
    var i = this.length - 1;
    if (string(name)) {
      this[i].properties.push({
        name: name,
        value: value
      });
    } else if (plainObject(name)) {
      var map = name;
      var propNames = Object.keys(map);
      for (var j = 0; j < propNames.length; j++) {
        var key = propNames[j];
        var mapVal = map[key];
        if (mapVal == null) {
          continue;
        }
        var prop = Style.properties[key] || Style.properties[dash2camel(key)];
        if (prop == null) {
          continue;
        }
        var _name = prop.name;
        var _value = mapVal;
        this[i].properties.push({
          name: _name,
          value: _value
        });
      }
    }
    return this; // chaining
  };

  sheetfn.style = sheetfn.css;

  // generate a real style object from the dummy stylesheet
  sheetfn.generateStyle = function (cy) {
    var style = new Style(cy);
    return this.appendToStyle(style);
  };

  // append a dummy stylesheet object on a real style object
  sheetfn.appendToStyle = function (style) {
    for (var i = 0; i < this.length; i++) {
      var context = this[i];
      var selector = context.selector;
      var props = context.properties;
      style.selector(selector); // apply selector

      for (var j = 0; j < props.length; j++) {
        var prop = props[j];
        style.css(prop.name, prop.value); // apply property
      }
    }

    return style;
  };

  var version = "3.28.1";

  var cytoscape = function cytoscape(options) {
    // if no options specified, use default
    if (options === undefined) {
      options = {};
    }

    // create instance
    if (plainObject(options)) {
      return new Core(options);
    }

    // allow for registration of extensions
    else if (string(options)) {
      return extension.apply(extension, arguments);
    }
  };

  // e.g. cytoscape.use( require('cytoscape-foo'), bar )
  cytoscape.use = function (ext) {
    var args = Array.prototype.slice.call(arguments, 1); // args to pass to ext

    args.unshift(cytoscape); // cytoscape is first arg to ext

    ext.apply(null, args);
    return this;
  };
  cytoscape.warnings = function (bool) {
    return warnings(bool);
  };

  // replaced by build system
  cytoscape.version = version;

  // expose public apis (mostly for extensions)
  cytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet;

  return cytoscape;

}));


/***/ }),

/***/ 82241:
/***/ (function(module) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory();
	else {}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_543__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_543__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_543__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_543__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_543__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_543__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_543__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_543__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_543__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_543__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_543__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_543__(__nested_webpack_require_543__.s = 26);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function LayoutConstants() {}

/**
 * Layout Quality: 0:draft, 1:default, 2:proof
 */
LayoutConstants.QUALITY = 1;

/**
 * Default parameters
 */
LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false;
LayoutConstants.DEFAULT_INCREMENTAL = false;
LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true;
LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false;
LayoutConstants.DEFAULT_ANIMATION_PERIOD = 50;
LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false;

// -----------------------------------------------------------------------------
// Section: General other constants
// -----------------------------------------------------------------------------
/*
 * Margins of a graph to be applied on bouding rectangle of its contents. We
 * assume margins on all four sides to be uniform.
 */
LayoutConstants.DEFAULT_GRAPH_MARGIN = 15;

/*
 * Whether to consider labels in node dimensions or not
 */
LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false;

/*
 * Default dimension of a non-compound node.
 */
LayoutConstants.SIMPLE_NODE_SIZE = 40;

/*
 * Default dimension of a non-compound node.
 */
LayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2;

/*
 * Empty compound node size. When a compound node is empty, its both
 * dimensions should be of this value.
 */
LayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40;

/*
 * Minimum length that an edge should take during layout
 */
LayoutConstants.MIN_EDGE_LENGTH = 1;

/*
 * World boundaries that layout operates on
 */
LayoutConstants.WORLD_BOUNDARY = 1000000;

/*
 * World boundaries that random positioning can be performed with
 */
LayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000;

/*
 * Coordinates of the world center
 */
LayoutConstants.WORLD_CENTER_X = 1200;
LayoutConstants.WORLD_CENTER_Y = 900;

module.exports = LayoutConstants;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_4947__) {

"use strict";


var LGraphObject = __nested_webpack_require_4947__(2);
var IGeometry = __nested_webpack_require_4947__(8);
var IMath = __nested_webpack_require_4947__(9);

function LEdge(source, target, vEdge) {
  LGraphObject.call(this, vEdge);

  this.isOverlapingSourceAndTarget = false;
  this.vGraphObject = vEdge;
  this.bendpoints = [];
  this.source = source;
  this.target = target;
}

LEdge.prototype = Object.create(LGraphObject.prototype);

for (var prop in LGraphObject) {
  LEdge[prop] = LGraphObject[prop];
}

LEdge.prototype.getSource = function () {
  return this.source;
};

LEdge.prototype.getTarget = function () {
  return this.target;
};

LEdge.prototype.isInterGraph = function () {
  return this.isInterGraph;
};

LEdge.prototype.getLength = function () {
  return this.length;
};

LEdge.prototype.isOverlapingSourceAndTarget = function () {
  return this.isOverlapingSourceAndTarget;
};

LEdge.prototype.getBendpoints = function () {
  return this.bendpoints;
};

LEdge.prototype.getLca = function () {
  return this.lca;
};

LEdge.prototype.getSourceInLca = function () {
  return this.sourceInLca;
};

LEdge.prototype.getTargetInLca = function () {
  return this.targetInLca;
};

LEdge.prototype.getOtherEnd = function (node) {
  if (this.source === node) {
    return this.target;
  } else if (this.target === node) {
    return this.source;
  } else {
    throw "Node is not incident with this edge";
  }
};

LEdge.prototype.getOtherEndInGraph = function (node, graph) {
  var otherEnd = this.getOtherEnd(node);
  var root = graph.getGraphManager().getRoot();

  while (true) {
    if (otherEnd.getOwner() == graph) {
      return otherEnd;
    }

    if (otherEnd.getOwner() == root) {
      break;
    }

    otherEnd = otherEnd.getOwner().getParent();
  }

  return null;
};

LEdge.prototype.updateLength = function () {
  var clipPointCoordinates = new Array(4);

  this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates);

  if (!this.isOverlapingSourceAndTarget) {
    this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2];
    this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3];

    if (Math.abs(this.lengthX) < 1.0) {
      this.lengthX = IMath.sign(this.lengthX);
    }

    if (Math.abs(this.lengthY) < 1.0) {
      this.lengthY = IMath.sign(this.lengthY);
    }

    this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);
  }
};

LEdge.prototype.updateLengthSimple = function () {
  this.lengthX = this.target.getCenterX() - this.source.getCenterX();
  this.lengthY = this.target.getCenterY() - this.source.getCenterY();

  if (Math.abs(this.lengthX) < 1.0) {
    this.lengthX = IMath.sign(this.lengthX);
  }

  if (Math.abs(this.lengthY) < 1.0) {
    this.lengthY = IMath.sign(this.lengthY);
  }

  this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);
};

module.exports = LEdge;

/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function LGraphObject(vGraphObject) {
  this.vGraphObject = vGraphObject;
}

module.exports = LGraphObject;

/***/ }),
/* 3 */
/***/ (function(module, exports, __nested_webpack_require_8167__) {

"use strict";


var LGraphObject = __nested_webpack_require_8167__(2);
var Integer = __nested_webpack_require_8167__(10);
var RectangleD = __nested_webpack_require_8167__(13);
var LayoutConstants = __nested_webpack_require_8167__(0);
var RandomSeed = __nested_webpack_require_8167__(16);
var PointD = __nested_webpack_require_8167__(4);

function LNode(gm, loc, size, vNode) {
  //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode)
  if (size == null && vNode == null) {
    vNode = loc;
  }

  LGraphObject.call(this, vNode);

  //Alternative constructor 2 : LNode(Layout layout, Object vNode)
  if (gm.graphManager != null) gm = gm.graphManager;

  this.estimatedSize = Integer.MIN_VALUE;
  this.inclusionTreeDepth = Integer.MAX_VALUE;
  this.vGraphObject = vNode;
  this.edges = [];
  this.graphManager = gm;

  if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD();
}

LNode.prototype = Object.create(LGraphObject.prototype);
for (var prop in LGraphObject) {
  LNode[prop] = LGraphObject[prop];
}

LNode.prototype.getEdges = function () {
  return this.edges;
};

LNode.prototype.getChild = function () {
  return this.child;
};

LNode.prototype.getOwner = function () {
  //  if (this.owner != null) {
  //    if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) {
  //      throw "assert failed";
  //    }
  //  }

  return this.owner;
};

LNode.prototype.getWidth = function () {
  return this.rect.width;
};

LNode.prototype.setWidth = function (width) {
  this.rect.width = width;
};

LNode.prototype.getHeight = function () {
  return this.rect.height;
};

LNode.prototype.setHeight = function (height) {
  this.rect.height = height;
};

LNode.prototype.getCenterX = function () {
  return this.rect.x + this.rect.width / 2;
};

LNode.prototype.getCenterY = function () {
  return this.rect.y + this.rect.height / 2;
};

LNode.prototype.getCenter = function () {
  return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2);
};

LNode.prototype.getLocation = function () {
  return new PointD(this.rect.x, this.rect.y);
};

LNode.prototype.getRect = function () {
  return this.rect;
};

LNode.prototype.getDiagonal = function () {
  return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height);
};

/**
 * This method returns half the diagonal length of this node.
 */
LNode.prototype.getHalfTheDiagonal = function () {
  return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2;
};

LNode.prototype.setRect = function (upperLeft, dimension) {
  this.rect.x = upperLeft.x;
  this.rect.y = upperLeft.y;
  this.rect.width = dimension.width;
  this.rect.height = dimension.height;
};

LNode.prototype.setCenter = function (cx, cy) {
  this.rect.x = cx - this.rect.width / 2;
  this.rect.y = cy - this.rect.height / 2;
};

LNode.prototype.setLocation = function (x, y) {
  this.rect.x = x;
  this.rect.y = y;
};

LNode.prototype.moveBy = function (dx, dy) {
  this.rect.x += dx;
  this.rect.y += dy;
};

LNode.prototype.getEdgeListToNode = function (to) {
  var edgeList = [];
  var edge;
  var self = this;

  self.edges.forEach(function (edge) {

    if (edge.target == to) {
      if (edge.source != self) throw "Incorrect edge source!";

      edgeList.push(edge);
    }
  });

  return edgeList;
};

LNode.prototype.getEdgesBetween = function (other) {
  var edgeList = [];
  var edge;

  var self = this;
  self.edges.forEach(function (edge) {

    if (!(edge.source == self || edge.target == self)) throw "Incorrect edge source and/or target";

    if (edge.target == other || edge.source == other) {
      edgeList.push(edge);
    }
  });

  return edgeList;
};

LNode.prototype.getNeighborsList = function () {
  var neighbors = new Set();

  var self = this;
  self.edges.forEach(function (edge) {

    if (edge.source == self) {
      neighbors.add(edge.target);
    } else {
      if (edge.target != self) {
        throw "Incorrect incidency!";
      }

      neighbors.add(edge.source);
    }
  });

  return neighbors;
};

LNode.prototype.withChildren = function () {
  var withNeighborsList = new Set();
  var childNode;
  var children;

  withNeighborsList.add(this);

  if (this.child != null) {
    var nodes = this.child.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      childNode = nodes[i];
      children = childNode.withChildren();
      children.forEach(function (node) {
        withNeighborsList.add(node);
      });
    }
  }

  return withNeighborsList;
};

LNode.prototype.getNoOfChildren = function () {
  var noOfChildren = 0;
  var childNode;

  if (this.child == null) {
    noOfChildren = 1;
  } else {
    var nodes = this.child.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      childNode = nodes[i];

      noOfChildren += childNode.getNoOfChildren();
    }
  }

  if (noOfChildren == 0) {
    noOfChildren = 1;
  }
  return noOfChildren;
};

LNode.prototype.getEstimatedSize = function () {
  if (this.estimatedSize == Integer.MIN_VALUE) {
    throw "assert failed";
  }
  return this.estimatedSize;
};

LNode.prototype.calcEstimatedSize = function () {
  if (this.child == null) {
    return this.estimatedSize = (this.rect.width + this.rect.height) / 2;
  } else {
    this.estimatedSize = this.child.calcEstimatedSize();
    this.rect.width = this.estimatedSize;
    this.rect.height = this.estimatedSize;

    return this.estimatedSize;
  }
};

LNode.prototype.scatter = function () {
  var randomCenterX;
  var randomCenterY;

  var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY;
  var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY;
  randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX;

  var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY;
  var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY;
  randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY;

  this.rect.x = randomCenterX;
  this.rect.y = randomCenterY;
};

LNode.prototype.updateBounds = function () {
  if (this.getChild() == null) {
    throw "assert failed";
  }
  if (this.getChild().getNodes().length != 0) {
    // wrap the children nodes by re-arranging the boundaries
    var childGraph = this.getChild();
    childGraph.updateBounds(true);

    this.rect.x = childGraph.getLeft();
    this.rect.y = childGraph.getTop();

    this.setWidth(childGraph.getRight() - childGraph.getLeft());
    this.setHeight(childGraph.getBottom() - childGraph.getTop());

    // Update compound bounds considering its label properties    
    if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {

      var width = childGraph.getRight() - childGraph.getLeft();
      var height = childGraph.getBottom() - childGraph.getTop();

      if (this.labelWidth > width) {
        this.rect.x -= (this.labelWidth - width) / 2;
        this.setWidth(this.labelWidth);
      }

      if (this.labelHeight > height) {
        if (this.labelPos == "center") {
          this.rect.y -= (this.labelHeight - height) / 2;
        } else if (this.labelPos == "top") {
          this.rect.y -= this.labelHeight - height;
        }
        this.setHeight(this.labelHeight);
      }
    }
  }
};

LNode.prototype.getInclusionTreeDepth = function () {
  if (this.inclusionTreeDepth == Integer.MAX_VALUE) {
    throw "assert failed";
  }
  return this.inclusionTreeDepth;
};

LNode.prototype.transform = function (trans) {
  var left = this.rect.x;

  if (left > LayoutConstants.WORLD_BOUNDARY) {
    left = LayoutConstants.WORLD_BOUNDARY;
  } else if (left < -LayoutConstants.WORLD_BOUNDARY) {
    left = -LayoutConstants.WORLD_BOUNDARY;
  }

  var top = this.rect.y;

  if (top > LayoutConstants.WORLD_BOUNDARY) {
    top = LayoutConstants.WORLD_BOUNDARY;
  } else if (top < -LayoutConstants.WORLD_BOUNDARY) {
    top = -LayoutConstants.WORLD_BOUNDARY;
  }

  var leftTop = new PointD(left, top);
  var vLeftTop = trans.inverseTransformPoint(leftTop);

  this.setLocation(vLeftTop.x, vLeftTop.y);
};

LNode.prototype.getLeft = function () {
  return this.rect.x;
};

LNode.prototype.getRight = function () {
  return this.rect.x + this.rect.width;
};

LNode.prototype.getTop = function () {
  return this.rect.y;
};

LNode.prototype.getBottom = function () {
  return this.rect.y + this.rect.height;
};

LNode.prototype.getParent = function () {
  if (this.owner == null) {
    return null;
  }

  return this.owner.getParent();
};

module.exports = LNode;

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function PointD(x, y) {
  if (x == null && y == null) {
    this.x = 0;
    this.y = 0;
  } else {
    this.x = x;
    this.y = y;
  }
}

PointD.prototype.getX = function () {
  return this.x;
};

PointD.prototype.getY = function () {
  return this.y;
};

PointD.prototype.setX = function (x) {
  this.x = x;
};

PointD.prototype.setY = function (y) {
  this.y = y;
};

PointD.prototype.getDifference = function (pt) {
  return new DimensionD(this.x - pt.x, this.y - pt.y);
};

PointD.prototype.getCopy = function () {
  return new PointD(this.x, this.y);
};

PointD.prototype.translate = function (dim) {
  this.x += dim.width;
  this.y += dim.height;
  return this;
};

module.exports = PointD;

/***/ }),
/* 5 */
/***/ (function(module, exports, __nested_webpack_require_17549__) {

"use strict";


var LGraphObject = __nested_webpack_require_17549__(2);
var Integer = __nested_webpack_require_17549__(10);
var LayoutConstants = __nested_webpack_require_17549__(0);
var LGraphManager = __nested_webpack_require_17549__(6);
var LNode = __nested_webpack_require_17549__(3);
var LEdge = __nested_webpack_require_17549__(1);
var RectangleD = __nested_webpack_require_17549__(13);
var Point = __nested_webpack_require_17549__(12);
var LinkedList = __nested_webpack_require_17549__(11);

function LGraph(parent, obj2, vGraph) {
  LGraphObject.call(this, vGraph);
  this.estimatedSize = Integer.MIN_VALUE;
  this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN;
  this.edges = [];
  this.nodes = [];
  this.isConnected = false;
  this.parent = parent;

  if (obj2 != null && obj2 instanceof LGraphManager) {
    this.graphManager = obj2;
  } else if (obj2 != null && obj2 instanceof Layout) {
    this.graphManager = obj2.graphManager;
  }
}

LGraph.prototype = Object.create(LGraphObject.prototype);
for (var prop in LGraphObject) {
  LGraph[prop] = LGraphObject[prop];
}

LGraph.prototype.getNodes = function () {
  return this.nodes;
};

LGraph.prototype.getEdges = function () {
  return this.edges;
};

LGraph.prototype.getGraphManager = function () {
  return this.graphManager;
};

LGraph.prototype.getParent = function () {
  return this.parent;
};

LGraph.prototype.getLeft = function () {
  return this.left;
};

LGraph.prototype.getRight = function () {
  return this.right;
};

LGraph.prototype.getTop = function () {
  return this.top;
};

LGraph.prototype.getBottom = function () {
  return this.bottom;
};

LGraph.prototype.isConnected = function () {
  return this.isConnected;
};

LGraph.prototype.add = function (obj1, sourceNode, targetNode) {
  if (sourceNode == null && targetNode == null) {
    var newNode = obj1;
    if (this.graphManager == null) {
      throw "Graph has no graph mgr!";
    }
    if (this.getNodes().indexOf(newNode) > -1) {
      throw "Node already in graph!";
    }
    newNode.owner = this;
    this.getNodes().push(newNode);

    return newNode;
  } else {
    var newEdge = obj1;
    if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) {
      throw "Source or target not in graph!";
    }

    if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) {
      throw "Both owners must be this graph!";
    }

    if (sourceNode.owner != targetNode.owner) {
      return null;
    }

    // set source and target
    newEdge.source = sourceNode;
    newEdge.target = targetNode;

    // set as intra-graph edge
    newEdge.isInterGraph = false;

    // add to graph edge list
    this.getEdges().push(newEdge);

    // add to incidency lists
    sourceNode.edges.push(newEdge);

    if (targetNode != sourceNode) {
      targetNode.edges.push(newEdge);
    }

    return newEdge;
  }
};

LGraph.prototype.remove = function (obj) {
  var node = obj;
  if (obj instanceof LNode) {
    if (node == null) {
      throw "Node is null!";
    }
    if (!(node.owner != null && node.owner == this)) {
      throw "Owner graph is invalid!";
    }
    if (this.graphManager == null) {
      throw "Owner graph manager is invalid!";
    }
    // remove incident edges first (make a copy to do it safely)
    var edgesToBeRemoved = node.edges.slice();
    var edge;
    var s = edgesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      edge = edgesToBeRemoved[i];

      if (edge.isInterGraph) {
        this.graphManager.remove(edge);
      } else {
        edge.source.owner.remove(edge);
      }
    }

    // now the node itself
    var index = this.nodes.indexOf(node);
    if (index == -1) {
      throw "Node not in owner node list!";
    }

    this.nodes.splice(index, 1);
  } else if (obj instanceof LEdge) {
    var edge = obj;
    if (edge == null) {
      throw "Edge is null!";
    }
    if (!(edge.source != null && edge.target != null)) {
      throw "Source and/or target is null!";
    }
    if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) {
      throw "Source and/or target owner is invalid!";
    }

    var sourceIndex = edge.source.edges.indexOf(edge);
    var targetIndex = edge.target.edges.indexOf(edge);
    if (!(sourceIndex > -1 && targetIndex > -1)) {
      throw "Source and/or target doesn't know this edge!";
    }

    edge.source.edges.splice(sourceIndex, 1);

    if (edge.target != edge.source) {
      edge.target.edges.splice(targetIndex, 1);
    }

    var index = edge.source.owner.getEdges().indexOf(edge);
    if (index == -1) {
      throw "Not in owner's edge list!";
    }

    edge.source.owner.getEdges().splice(index, 1);
  }
};

LGraph.prototype.updateLeftTop = function () {
  var top = Integer.MAX_VALUE;
  var left = Integer.MAX_VALUE;
  var nodeTop;
  var nodeLeft;
  var margin;

  var nodes = this.getNodes();
  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    nodeTop = lNode.getTop();
    nodeLeft = lNode.getLeft();

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (left > nodeLeft) {
      left = nodeLeft;
    }
  }

  // Do we have any nodes in this graph?
  if (top == Integer.MAX_VALUE) {
    return null;
  }

  if (nodes[0].getParent().paddingLeft != undefined) {
    margin = nodes[0].getParent().paddingLeft;
  } else {
    margin = this.margin;
  }

  this.left = left - margin;
  this.top = top - margin;

  // Apply the margins and return the result
  return new Point(this.left, this.top);
};

LGraph.prototype.updateBounds = function (recursive) {
  // calculate bounds
  var left = Integer.MAX_VALUE;
  var right = -Integer.MAX_VALUE;
  var top = Integer.MAX_VALUE;
  var bottom = -Integer.MAX_VALUE;
  var nodeLeft;
  var nodeRight;
  var nodeTop;
  var nodeBottom;
  var margin;

  var nodes = this.nodes;
  var s = nodes.length;
  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];

    if (recursive && lNode.child != null) {
      lNode.updateBounds();
    }
    nodeLeft = lNode.getLeft();
    nodeRight = lNode.getRight();
    nodeTop = lNode.getTop();
    nodeBottom = lNode.getBottom();

    if (left > nodeLeft) {
      left = nodeLeft;
    }

    if (right < nodeRight) {
      right = nodeRight;
    }

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (bottom < nodeBottom) {
      bottom = nodeBottom;
    }
  }

  var boundingRect = new RectangleD(left, top, right - left, bottom - top);
  if (left == Integer.MAX_VALUE) {
    this.left = this.parent.getLeft();
    this.right = this.parent.getRight();
    this.top = this.parent.getTop();
    this.bottom = this.parent.getBottom();
  }

  if (nodes[0].getParent().paddingLeft != undefined) {
    margin = nodes[0].getParent().paddingLeft;
  } else {
    margin = this.margin;
  }

  this.left = boundingRect.x - margin;
  this.right = boundingRect.x + boundingRect.width + margin;
  this.top = boundingRect.y - margin;
  this.bottom = boundingRect.y + boundingRect.height + margin;
};

LGraph.calculateBounds = function (nodes) {
  var left = Integer.MAX_VALUE;
  var right = -Integer.MAX_VALUE;
  var top = Integer.MAX_VALUE;
  var bottom = -Integer.MAX_VALUE;
  var nodeLeft;
  var nodeRight;
  var nodeTop;
  var nodeBottom;

  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    nodeLeft = lNode.getLeft();
    nodeRight = lNode.getRight();
    nodeTop = lNode.getTop();
    nodeBottom = lNode.getBottom();

    if (left > nodeLeft) {
      left = nodeLeft;
    }

    if (right < nodeRight) {
      right = nodeRight;
    }

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (bottom < nodeBottom) {
      bottom = nodeBottom;
    }
  }

  var boundingRect = new RectangleD(left, top, right - left, bottom - top);

  return boundingRect;
};

LGraph.prototype.getInclusionTreeDepth = function () {
  if (this == this.graphManager.getRoot()) {
    return 1;
  } else {
    return this.parent.getInclusionTreeDepth();
  }
};

LGraph.prototype.getEstimatedSize = function () {
  if (this.estimatedSize == Integer.MIN_VALUE) {
    throw "assert failed";
  }
  return this.estimatedSize;
};

LGraph.prototype.calcEstimatedSize = function () {
  var size = 0;
  var nodes = this.nodes;
  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    size += lNode.calcEstimatedSize();
  }

  if (size == 0) {
    this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE;
  } else {
    this.estimatedSize = size / Math.sqrt(this.nodes.length);
  }

  return this.estimatedSize;
};

LGraph.prototype.updateConnected = function () {
  var self = this;
  if (this.nodes.length == 0) {
    this.isConnected = true;
    return;
  }

  var queue = new LinkedList();
  var visited = new Set();
  var currentNode = this.nodes[0];
  var neighborEdges;
  var currentNeighbor;
  var childrenOfNode = currentNode.withChildren();
  childrenOfNode.forEach(function (node) {
    queue.push(node);
    visited.add(node);
  });

  while (queue.length !== 0) {
    currentNode = queue.shift();

    // Traverse all neighbors of this node
    neighborEdges = currentNode.getEdges();
    var size = neighborEdges.length;
    for (var i = 0; i < size; i++) {
      var neighborEdge = neighborEdges[i];
      currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this);

      // Add unvisited neighbors to the list to visit
      if (currentNeighbor != null && !visited.has(currentNeighbor)) {
        var childrenOfNeighbor = currentNeighbor.withChildren();

        childrenOfNeighbor.forEach(function (node) {
          queue.push(node);
          visited.add(node);
        });
      }
    }
  }

  this.isConnected = false;

  if (visited.size >= this.nodes.length) {
    var noOfVisitedInThisGraph = 0;

    visited.forEach(function (visitedNode) {
      if (visitedNode.owner == self) {
        noOfVisitedInThisGraph++;
      }
    });

    if (noOfVisitedInThisGraph == this.nodes.length) {
      this.isConnected = true;
    }
  }
};

module.exports = LGraph;

/***/ }),
/* 6 */
/***/ (function(module, exports, __nested_webpack_require_27617__) {

"use strict";


var LGraph;
var LEdge = __nested_webpack_require_27617__(1);

function LGraphManager(layout) {
  LGraph = __nested_webpack_require_27617__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now.
  this.layout = layout;

  this.graphs = [];
  this.edges = [];
}

LGraphManager.prototype.addRoot = function () {
  var ngraph = this.layout.newGraph();
  var nnode = this.layout.newNode(null);
  var root = this.add(ngraph, nnode);
  this.setRootGraph(root);
  return this.rootGraph;
};

LGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) {
  //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge
  if (newEdge == null && sourceNode == null && targetNode == null) {
    if (newGraph == null) {
      throw "Graph is null!";
    }
    if (parentNode == null) {
      throw "Parent node is null!";
    }
    if (this.graphs.indexOf(newGraph) > -1) {
      throw "Graph already in this graph mgr!";
    }

    this.graphs.push(newGraph);

    if (newGraph.parent != null) {
      throw "Already has a parent!";
    }
    if (parentNode.child != null) {
      throw "Already has a child!";
    }

    newGraph.parent = parentNode;
    parentNode.child = newGraph;

    return newGraph;
  } else {
    //change the order of the parameters
    targetNode = newEdge;
    sourceNode = parentNode;
    newEdge = newGraph;
    var sourceGraph = sourceNode.getOwner();
    var targetGraph = targetNode.getOwner();

    if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) {
      throw "Source not in this graph mgr!";
    }
    if (!(targetGraph != null && targetGraph.getGraphManager() == this)) {
      throw "Target not in this graph mgr!";
    }

    if (sourceGraph == targetGraph) {
      newEdge.isInterGraph = false;
      return sourceGraph.add(newEdge, sourceNode, targetNode);
    } else {
      newEdge.isInterGraph = true;

      // set source and target
      newEdge.source = sourceNode;
      newEdge.target = targetNode;

      // add edge to inter-graph edge list
      if (this.edges.indexOf(newEdge) > -1) {
        throw "Edge already in inter-graph edge list!";
      }

      this.edges.push(newEdge);

      // add edge to source and target incidency lists
      if (!(newEdge.source != null && newEdge.target != null)) {
        throw "Edge source and/or target is null!";
      }

      if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) {
        throw "Edge already in source and/or target incidency list!";
      }

      newEdge.source.edges.push(newEdge);
      newEdge.target.edges.push(newEdge);

      return newEdge;
    }
  }
};

LGraphManager.prototype.remove = function (lObj) {
  if (lObj instanceof LGraph) {
    var graph = lObj;
    if (graph.getGraphManager() != this) {
      throw "Graph not in this graph mgr";
    }
    if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) {
      throw "Invalid parent node!";
    }

    // first the edges (make a copy to do it safely)
    var edgesToBeRemoved = [];

    edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges());

    var edge;
    var s = edgesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      edge = edgesToBeRemoved[i];
      graph.remove(edge);
    }

    // then the nodes (make a copy to do it safely)
    var nodesToBeRemoved = [];

    nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes());

    var node;
    s = nodesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      node = nodesToBeRemoved[i];
      graph.remove(node);
    }

    // check if graph is the root
    if (graph == this.rootGraph) {
      this.setRootGraph(null);
    }

    // now remove the graph itself
    var index = this.graphs.indexOf(graph);
    this.graphs.splice(index, 1);

    // also reset the parent of the graph
    graph.parent = null;
  } else if (lObj instanceof LEdge) {
    edge = lObj;
    if (edge == null) {
      throw "Edge is null!";
    }
    if (!edge.isInterGraph) {
      throw "Not an inter-graph edge!";
    }
    if (!(edge.source != null && edge.target != null)) {
      throw "Source and/or target is null!";
    }

    // remove edge from source and target nodes' incidency lists

    if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) {
      throw "Source and/or target doesn't know this edge!";
    }

    var index = edge.source.edges.indexOf(edge);
    edge.source.edges.splice(index, 1);
    index = edge.target.edges.indexOf(edge);
    edge.target.edges.splice(index, 1);

    // remove edge from owner graph manager's inter-graph edge list

    if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) {
      throw "Edge owner graph or owner graph manager is null!";
    }
    if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) {
      throw "Not in owner graph manager's edge list!";
    }

    var index = edge.source.owner.getGraphManager().edges.indexOf(edge);
    edge.source.owner.getGraphManager().edges.splice(index, 1);
  }
};

LGraphManager.prototype.updateBounds = function () {
  this.rootGraph.updateBounds(true);
};

LGraphManager.prototype.getGraphs = function () {
  return this.graphs;
};

LGraphManager.prototype.getAllNodes = function () {
  if (this.allNodes == null) {
    var nodeList = [];
    var graphs = this.getGraphs();
    var s = graphs.length;
    for (var i = 0; i < s; i++) {
      nodeList = nodeList.concat(graphs[i].getNodes());
    }
    this.allNodes = nodeList;
  }
  return this.allNodes;
};

LGraphManager.prototype.resetAllNodes = function () {
  this.allNodes = null;
};

LGraphManager.prototype.resetAllEdges = function () {
  this.allEdges = null;
};

LGraphManager.prototype.resetAllNodesToApplyGravitation = function () {
  this.allNodesToApplyGravitation = null;
};

LGraphManager.prototype.getAllEdges = function () {
  if (this.allEdges == null) {
    var edgeList = [];
    var graphs = this.getGraphs();
    var s = graphs.length;
    for (var i = 0; i < graphs.length; i++) {
      edgeList = edgeList.concat(graphs[i].getEdges());
    }

    edgeList = edgeList.concat(this.edges);

    this.allEdges = edgeList;
  }
  return this.allEdges;
};

LGraphManager.prototype.getAllNodesToApplyGravitation = function () {
  return this.allNodesToApplyGravitation;
};

LGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) {
  if (this.allNodesToApplyGravitation != null) {
    throw "assert failed";
  }

  this.allNodesToApplyGravitation = nodeList;
};

LGraphManager.prototype.getRoot = function () {
  return this.rootGraph;
};

LGraphManager.prototype.setRootGraph = function (graph) {
  if (graph.getGraphManager() != this) {
    throw "Root not in this graph mgr!";
  }

  this.rootGraph = graph;
  // root graph must have a root node associated with it for convenience
  if (graph.parent == null) {
    graph.parent = this.layout.newNode("Root node");
  }
};

LGraphManager.prototype.getLayout = function () {
  return this.layout;
};

LGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) {
  if (!(firstNode != null && secondNode != null)) {
    throw "assert failed";
  }

  if (firstNode == secondNode) {
    return true;
  }
  // Is second node an ancestor of the first one?
  var ownerGraph = firstNode.getOwner();
  var parentNode;

  do {
    parentNode = ownerGraph.getParent();

    if (parentNode == null) {
      break;
    }

    if (parentNode == secondNode) {
      return true;
    }

    ownerGraph = parentNode.getOwner();
    if (ownerGraph == null) {
      break;
    }
  } while (true);
  // Is first node an ancestor of the second one?
  ownerGraph = secondNode.getOwner();

  do {
    parentNode = ownerGraph.getParent();

    if (parentNode == null) {
      break;
    }

    if (parentNode == firstNode) {
      return true;
    }

    ownerGraph = parentNode.getOwner();
    if (ownerGraph == null) {
      break;
    }
  } while (true);

  return false;
};

LGraphManager.prototype.calcLowestCommonAncestors = function () {
  var edge;
  var sourceNode;
  var targetNode;
  var sourceAncestorGraph;
  var targetAncestorGraph;

  var edges = this.getAllEdges();
  var s = edges.length;
  for (var i = 0; i < s; i++) {
    edge = edges[i];

    sourceNode = edge.source;
    targetNode = edge.target;
    edge.lca = null;
    edge.sourceInLca = sourceNode;
    edge.targetInLca = targetNode;

    if (sourceNode == targetNode) {
      edge.lca = sourceNode.getOwner();
      continue;
    }

    sourceAncestorGraph = sourceNode.getOwner();

    while (edge.lca == null) {
      edge.targetInLca = targetNode;
      targetAncestorGraph = targetNode.getOwner();

      while (edge.lca == null) {
        if (targetAncestorGraph == sourceAncestorGraph) {
          edge.lca = targetAncestorGraph;
          break;
        }

        if (targetAncestorGraph == this.rootGraph) {
          break;
        }

        if (edge.lca != null) {
          throw "assert failed";
        }
        edge.targetInLca = targetAncestorGraph.getParent();
        targetAncestorGraph = edge.targetInLca.getOwner();
      }

      if (sourceAncestorGraph == this.rootGraph) {
        break;
      }

      if (edge.lca == null) {
        edge.sourceInLca = sourceAncestorGraph.getParent();
        sourceAncestorGraph = edge.sourceInLca.getOwner();
      }
    }

    if (edge.lca == null) {
      throw "assert failed";
    }
  }
};

LGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) {
  if (firstNode == secondNode) {
    return firstNode.getOwner();
  }
  var firstOwnerGraph = firstNode.getOwner();

  do {
    if (firstOwnerGraph == null) {
      break;
    }
    var secondOwnerGraph = secondNode.getOwner();

    do {
      if (secondOwnerGraph == null) {
        break;
      }

      if (secondOwnerGraph == firstOwnerGraph) {
        return secondOwnerGraph;
      }
      secondOwnerGraph = secondOwnerGraph.getParent().getOwner();
    } while (true);

    firstOwnerGraph = firstOwnerGraph.getParent().getOwner();
  } while (true);

  return firstOwnerGraph;
};

LGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) {
  if (graph == null && depth == null) {
    graph = this.rootGraph;
    depth = 1;
  }
  var node;

  var nodes = graph.getNodes();
  var s = nodes.length;
  for (var i = 0; i < s; i++) {
    node = nodes[i];
    node.inclusionTreeDepth = depth;

    if (node.child != null) {
      this.calcInclusionTreeDepths(node.child, depth + 1);
    }
  }
};

LGraphManager.prototype.includesInvalidEdge = function () {
  var edge;

  var s = this.edges.length;
  for (var i = 0; i < s; i++) {
    edge = this.edges[i];

    if (this.isOneAncestorOfOther(edge.source, edge.target)) {
      return true;
    }
  }
  return false;
};

module.exports = LGraphManager;

/***/ }),
/* 7 */
/***/ (function(module, exports, __nested_webpack_require_38707__) {

"use strict";


var LayoutConstants = __nested_webpack_require_38707__(0);

function FDLayoutConstants() {}

//FDLayoutConstants inherits static props in LayoutConstants
for (var prop in LayoutConstants) {
  FDLayoutConstants[prop] = LayoutConstants[prop];
}

FDLayoutConstants.MAX_ITERATIONS = 2500;

FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50;
FDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45;
FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0;
FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4;
FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0;
FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8;
FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5;
FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true;
FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true;
FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3;
FDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33;
FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000;
FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000;
FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0;
FDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3;
FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0;
FDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100;
FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1;
FDLayoutConstants.MIN_EDGE_LENGTH = 1;
FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10;

module.exports = FDLayoutConstants;

/***/ }),
/* 8 */
/***/ (function(module, exports, __nested_webpack_require_40298__) {

"use strict";


/**
 * This class maintains a list of static geometry related utility methods.
 *
 *
 * Copyright: i-Vis Research Group, Bilkent University, 2007 - present
 */

var Point = __nested_webpack_require_40298__(12);

function IGeometry() {}

/**
 * This method calculates *half* the amount in x and y directions of the two
 * input rectangles needed to separate them keeping their respective
 * positioning, and returns the result in the input array. An input
 * separation buffer added to the amount in both directions. We assume that
 * the two rectangles do intersect.
 */
IGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) {
  if (!rectA.intersects(rectB)) {
    throw "assert failed";
  }

  var directions = new Array(2);

  this.decideDirectionsForOverlappingNodes(rectA, rectB, directions);

  overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x);
  overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y);

  // update the overlapping amounts for the following cases:
  if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) {
    /* Case x.1:
    *
    * rectA
    * 	|                       |
    * 	|        _________      |
    * 	|        |       |      |
    * 	|________|_______|______|
    * 			 |       |
    *           |       |
    *        rectB
    */
    overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight());
  } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) {
    /* Case x.2:
    *
    * rectB
    * 	|                       |
    * 	|        _________      |
    * 	|        |       |      |
    * 	|________|_______|______|
    * 			 |       |
    *           |       |
    *        rectA
    */
    overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight());
  }
  if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) {
    /* Case y.1:
     *          ________ rectA
     *         |
     *         |
     *   ______|____  rectB
     *         |    |
     *         |    |
     *   ______|____|
     *         |
     *         |
     *         |________
     *
     */
    overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom());
  } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) {
    /* Case y.2:
    *          ________ rectB
    *         |
    *         |
    *   ______|____  rectA
    *         |    |
    *         |    |
    *   ______|____|
    *         |
    *         |
    *         |________
    *
    */
    overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom());
  }

  // find slope of the line passes two centers
  var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX()));
  // if centers are overlapped
  if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) {
    // assume the slope is 1 (45 degree)
    slope = 1.0;
  }

  var moveByY = slope * overlapAmount[0];
  var moveByX = overlapAmount[1] / slope;
  if (overlapAmount[0] < moveByX) {
    moveByX = overlapAmount[0];
  } else {
    moveByY = overlapAmount[1];
  }
  // return half the amount so that if each rectangle is moved by these
  // amounts in opposite directions, overlap will be resolved
  overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer);
  overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer);
};

/**
 * This method decides the separation direction of overlapping nodes
 *
 * if directions[0] = -1, then rectA goes left
 * if directions[0] = 1,  then rectA goes right
 * if directions[1] = -1, then rectA goes up
 * if directions[1] = 1,  then rectA goes down
 */
IGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) {
  if (rectA.getCenterX() < rectB.getCenterX()) {
    directions[0] = -1;
  } else {
    directions[0] = 1;
  }

  if (rectA.getCenterY() < rectB.getCenterY()) {
    directions[1] = -1;
  } else {
    directions[1] = 1;
  }
};

/**
 * This method calculates the intersection (clipping) points of the two
 * input rectangles with line segment defined by the centers of these two
 * rectangles. The clipping points are saved in the input double array and
 * whether or not the two rectangles overlap is returned.
 */
IGeometry.getIntersection2 = function (rectA, rectB, result) {
  //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB
  var p1x = rectA.getCenterX();
  var p1y = rectA.getCenterY();
  var p2x = rectB.getCenterX();
  var p2y = rectB.getCenterY();

  //if two rectangles intersect, then clipping points are centers
  if (rectA.intersects(rectB)) {
    result[0] = p1x;
    result[1] = p1y;
    result[2] = p2x;
    result[3] = p2y;
    return true;
  }
  //variables for rectA
  var topLeftAx = rectA.getX();
  var topLeftAy = rectA.getY();
  var topRightAx = rectA.getRight();
  var bottomLeftAx = rectA.getX();
  var bottomLeftAy = rectA.getBottom();
  var bottomRightAx = rectA.getRight();
  var halfWidthA = rectA.getWidthHalf();
  var halfHeightA = rectA.getHeightHalf();
  //variables for rectB
  var topLeftBx = rectB.getX();
  var topLeftBy = rectB.getY();
  var topRightBx = rectB.getRight();
  var bottomLeftBx = rectB.getX();
  var bottomLeftBy = rectB.getBottom();
  var bottomRightBx = rectB.getRight();
  var halfWidthB = rectB.getWidthHalf();
  var halfHeightB = rectB.getHeightHalf();

  //flag whether clipping points are found
  var clipPointAFound = false;
  var clipPointBFound = false;

  // line is vertical
  if (p1x === p2x) {
    if (p1y > p2y) {
      result[0] = p1x;
      result[1] = topLeftAy;
      result[2] = p2x;
      result[3] = bottomLeftBy;
      return false;
    } else if (p1y < p2y) {
      result[0] = p1x;
      result[1] = bottomLeftAy;
      result[2] = p2x;
      result[3] = topLeftBy;
      return false;
    } else {
      //not line, return null;
    }
  }
  // line is horizontal
  else if (p1y === p2y) {
      if (p1x > p2x) {
        result[0] = topLeftAx;
        result[1] = p1y;
        result[2] = topRightBx;
        result[3] = p2y;
        return false;
      } else if (p1x < p2x) {
        result[0] = topRightAx;
        result[1] = p1y;
        result[2] = topLeftBx;
        result[3] = p2y;
        return false;
      } else {
        //not valid line, return null;
      }
    } else {
      //slopes of rectA's and rectB's diagonals
      var slopeA = rectA.height / rectA.width;
      var slopeB = rectB.height / rectB.width;

      //slope of line between center of rectA and center of rectB
      var slopePrime = (p2y - p1y) / (p2x - p1x);
      var cardinalDirectionA = void 0;
      var cardinalDirectionB = void 0;
      var tempPointAx = void 0;
      var tempPointAy = void 0;
      var tempPointBx = void 0;
      var tempPointBy = void 0;

      //determine whether clipping point is the corner of nodeA
      if (-slopeA === slopePrime) {
        if (p1x > p2x) {
          result[0] = bottomLeftAx;
          result[1] = bottomLeftAy;
          clipPointAFound = true;
        } else {
          result[0] = topRightAx;
          result[1] = topLeftAy;
          clipPointAFound = true;
        }
      } else if (slopeA === slopePrime) {
        if (p1x > p2x) {
          result[0] = topLeftAx;
          result[1] = topLeftAy;
          clipPointAFound = true;
        } else {
          result[0] = bottomRightAx;
          result[1] = bottomLeftAy;
          clipPointAFound = true;
        }
      }

      //determine whether clipping point is the corner of nodeB
      if (-slopeB === slopePrime) {
        if (p2x > p1x) {
          result[2] = bottomLeftBx;
          result[3] = bottomLeftBy;
          clipPointBFound = true;
        } else {
          result[2] = topRightBx;
          result[3] = topLeftBy;
          clipPointBFound = true;
        }
      } else if (slopeB === slopePrime) {
        if (p2x > p1x) {
          result[2] = topLeftBx;
          result[3] = topLeftBy;
          clipPointBFound = true;
        } else {
          result[2] = bottomRightBx;
          result[3] = bottomLeftBy;
          clipPointBFound = true;
        }
      }

      //if both clipping points are corners
      if (clipPointAFound && clipPointBFound) {
        return false;
      }

      //determine Cardinal Direction of rectangles
      if (p1x > p2x) {
        if (p1y > p2y) {
          cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4);
          cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2);
        } else {
          cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3);
          cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1);
        }
      } else {
        if (p1y > p2y) {
          cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1);
          cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3);
        } else {
          cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2);
          cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4);
        }
      }
      //calculate clipping Point if it is not found before
      if (!clipPointAFound) {
        switch (cardinalDirectionA) {
          case 1:
            tempPointAy = topLeftAy;
            tempPointAx = p1x + -halfHeightA / slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 2:
            tempPointAx = bottomRightAx;
            tempPointAy = p1y + halfWidthA * slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 3:
            tempPointAy = bottomLeftAy;
            tempPointAx = p1x + halfHeightA / slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 4:
            tempPointAx = bottomLeftAx;
            tempPointAy = p1y + -halfWidthA * slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
        }
      }
      if (!clipPointBFound) {
        switch (cardinalDirectionB) {
          case 1:
            tempPointBy = topLeftBy;
            tempPointBx = p2x + -halfHeightB / slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 2:
            tempPointBx = bottomRightBx;
            tempPointBy = p2y + halfWidthB * slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 3:
            tempPointBy = bottomLeftBy;
            tempPointBx = p2x + halfHeightB / slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 4:
            tempPointBx = bottomLeftBx;
            tempPointBy = p2y + -halfWidthB * slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
        }
      }
    }
  return false;
};

/**
 * This method returns in which cardinal direction does input point stays
 * 1: North
 * 2: East
 * 3: South
 * 4: West
 */
IGeometry.getCardinalDirection = function (slope, slopePrime, line) {
  if (slope > slopePrime) {
    return line;
  } else {
    return 1 + line % 4;
  }
};

/**
 * This method calculates the intersection of the two lines defined by
 * point pairs (s1,s2) and (f1,f2).
 */
IGeometry.getIntersection = function (s1, s2, f1, f2) {
  if (f2 == null) {
    return this.getIntersection2(s1, s2, f1);
  }

  var x1 = s1.x;
  var y1 = s1.y;
  var x2 = s2.x;
  var y2 = s2.y;
  var x3 = f1.x;
  var y3 = f1.y;
  var x4 = f2.x;
  var y4 = f2.y;
  var x = void 0,
      y = void 0; // intersection point
  var a1 = void 0,
      a2 = void 0,
      b1 = void 0,
      b2 = void 0,
      c1 = void 0,
      c2 = void 0; // coefficients of line eqns.
  var denom = void 0;

  a1 = y2 - y1;
  b1 = x1 - x2;
  c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 }

  a2 = y4 - y3;
  b2 = x3 - x4;
  c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 }

  denom = a1 * b2 - a2 * b1;

  if (denom === 0) {
    return null;
  }

  x = (b1 * c2 - b2 * c1) / denom;
  y = (a2 * c1 - a1 * c2) / denom;

  return new Point(x, y);
};

/**
 * This method finds and returns the angle of the vector from the + x-axis
 * in clockwise direction (compatible w/ Java coordinate system!).
 */
IGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) {
  var C_angle = void 0;

  if (Cx !== Nx) {
    C_angle = Math.atan((Ny - Cy) / (Nx - Cx));

    if (Nx < Cx) {
      C_angle += Math.PI;
    } else if (Ny < Cy) {
      C_angle += this.TWO_PI;
    }
  } else if (Ny < Cy) {
    C_angle = this.ONE_AND_HALF_PI; // 270 degrees
  } else {
    C_angle = this.HALF_PI; // 90 degrees
  }

  return C_angle;
};

/**
 * This method checks whether the given two line segments (one with point
 * p1 and p2, the other with point p3 and p4) intersect at a point other
 * than these points.
 */
IGeometry.doIntersect = function (p1, p2, p3, p4) {
  var a = p1.x;
  var b = p1.y;
  var c = p2.x;
  var d = p2.y;
  var p = p3.x;
  var q = p3.y;
  var r = p4.x;
  var s = p4.y;
  var det = (c - a) * (s - q) - (r - p) * (d - b);

  if (det === 0) {
    return false;
  } else {
    var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
    var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
    return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;
  }
};

// -----------------------------------------------------------------------------
// Section: Class Constants
// -----------------------------------------------------------------------------
/**
 * Some useful pre-calculated constants
 */
IGeometry.HALF_PI = 0.5 * Math.PI;
IGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI;
IGeometry.TWO_PI = 2.0 * Math.PI;
IGeometry.THREE_PI = 3.0 * Math.PI;

module.exports = IGeometry;

/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function IMath() {}

/**
 * This method returns the sign of the input value.
 */
IMath.sign = function (value) {
  if (value > 0) {
    return 1;
  } else if (value < 0) {
    return -1;
  } else {
    return 0;
  }
};

IMath.floor = function (value) {
  return value < 0 ? Math.ceil(value) : Math.floor(value);
};

IMath.ceil = function (value) {
  return value < 0 ? Math.floor(value) : Math.ceil(value);
};

module.exports = IMath;

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function Integer() {}

Integer.MAX_VALUE = 2147483647;
Integer.MIN_VALUE = -2147483648;

module.exports = Integer;

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var nodeFrom = function nodeFrom(value) {
  return { value: value, next: null, prev: null };
};

var add = function add(prev, node, next, list) {
  if (prev !== null) {
    prev.next = node;
  } else {
    list.head = node;
  }

  if (next !== null) {
    next.prev = node;
  } else {
    list.tail = node;
  }

  node.prev = prev;
  node.next = next;

  list.length++;

  return node;
};

var _remove = function _remove(node, list) {
  var prev = node.prev,
      next = node.next;


  if (prev !== null) {
    prev.next = next;
  } else {
    list.head = next;
  }

  if (next !== null) {
    next.prev = prev;
  } else {
    list.tail = prev;
  }

  node.prev = node.next = null;

  list.length--;

  return node;
};

var LinkedList = function () {
  function LinkedList(vals) {
    var _this = this;

    _classCallCheck(this, LinkedList);

    this.length = 0;
    this.head = null;
    this.tail = null;

    if (vals != null) {
      vals.forEach(function (v) {
        return _this.push(v);
      });
    }
  }

  _createClass(LinkedList, [{
    key: "size",
    value: function size() {
      return this.length;
    }
  }, {
    key: "insertBefore",
    value: function insertBefore(val, otherNode) {
      return add(otherNode.prev, nodeFrom(val), otherNode, this);
    }
  }, {
    key: "insertAfter",
    value: function insertAfter(val, otherNode) {
      return add(otherNode, nodeFrom(val), otherNode.next, this);
    }
  }, {
    key: "insertNodeBefore",
    value: function insertNodeBefore(newNode, otherNode) {
      return add(otherNode.prev, newNode, otherNode, this);
    }
  }, {
    key: "insertNodeAfter",
    value: function insertNodeAfter(newNode, otherNode) {
      return add(otherNode, newNode, otherNode.next, this);
    }
  }, {
    key: "push",
    value: function push(val) {
      return add(this.tail, nodeFrom(val), null, this);
    }
  }, {
    key: "unshift",
    value: function unshift(val) {
      return add(null, nodeFrom(val), this.head, this);
    }
  }, {
    key: "remove",
    value: function remove(node) {
      return _remove(node, this);
    }
  }, {
    key: "pop",
    value: function pop() {
      return _remove(this.tail, this).value;
    }
  }, {
    key: "popNode",
    value: function popNode() {
      return _remove(this.tail, this);
    }
  }, {
    key: "shift",
    value: function shift() {
      return _remove(this.head, this).value;
    }
  }, {
    key: "shiftNode",
    value: function shiftNode() {
      return _remove(this.head, this);
    }
  }, {
    key: "get_object_at",
    value: function get_object_at(index) {
      if (index <= this.length()) {
        var i = 1;
        var current = this.head;
        while (i < index) {
          current = current.next;
          i++;
        }
        return current.value;
      }
    }
  }, {
    key: "set_object_at",
    value: function set_object_at(index, value) {
      if (index <= this.length()) {
        var i = 1;
        var current = this.head;
        while (i < index) {
          current = current.next;
          i++;
        }
        current.value = value;
      }
    }
  }]);

  return LinkedList;
}();

module.exports = LinkedList;

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


/*
 *This class is the javascript implementation of the Point.java class in jdk
 */
function Point(x, y, p) {
  this.x = null;
  this.y = null;
  if (x == null && y == null && p == null) {
    this.x = 0;
    this.y = 0;
  } else if (typeof x == 'number' && typeof y == 'number' && p == null) {
    this.x = x;
    this.y = y;
  } else if (x.constructor.name == 'Point' && y == null && p == null) {
    p = x;
    this.x = p.x;
    this.y = p.y;
  }
}

Point.prototype.getX = function () {
  return this.x;
};

Point.prototype.getY = function () {
  return this.y;
};

Point.prototype.getLocation = function () {
  return new Point(this.x, this.y);
};

Point.prototype.setLocation = function (x, y, p) {
  if (x.constructor.name == 'Point' && y == null && p == null) {
    p = x;
    this.setLocation(p.x, p.y);
  } else if (typeof x == 'number' && typeof y == 'number' && p == null) {
    //if both parameters are integer just move (x,y) location
    if (parseInt(x) == x && parseInt(y) == y) {
      this.move(x, y);
    } else {
      this.x = Math.floor(x + 0.5);
      this.y = Math.floor(y + 0.5);
    }
  }
};

Point.prototype.move = function (x, y) {
  this.x = x;
  this.y = y;
};

Point.prototype.translate = function (dx, dy) {
  this.x += dx;
  this.y += dy;
};

Point.prototype.equals = function (obj) {
  if (obj.constructor.name == "Point") {
    var pt = obj;
    return this.x == pt.x && this.y == pt.y;
  }
  return this == obj;
};

Point.prototype.toString = function () {
  return new Point().constructor.name + "[x=" + this.x + ",y=" + this.y + "]";
};

module.exports = Point;

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function RectangleD(x, y, width, height) {
  this.x = 0;
  this.y = 0;
  this.width = 0;
  this.height = 0;

  if (x != null && y != null && width != null && height != null) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
  }
}

RectangleD.prototype.getX = function () {
  return this.x;
};

RectangleD.prototype.setX = function (x) {
  this.x = x;
};

RectangleD.prototype.getY = function () {
  return this.y;
};

RectangleD.prototype.setY = function (y) {
  this.y = y;
};

RectangleD.prototype.getWidth = function () {
  return this.width;
};

RectangleD.prototype.setWidth = function (width) {
  this.width = width;
};

RectangleD.prototype.getHeight = function () {
  return this.height;
};

RectangleD.prototype.setHeight = function (height) {
  this.height = height;
};

RectangleD.prototype.getRight = function () {
  return this.x + this.width;
};

RectangleD.prototype.getBottom = function () {
  return this.y + this.height;
};

RectangleD.prototype.intersects = function (a) {
  if (this.getRight() < a.x) {
    return false;
  }

  if (this.getBottom() < a.y) {
    return false;
  }

  if (a.getRight() < this.x) {
    return false;
  }

  if (a.getBottom() < this.y) {
    return false;
  }

  return true;
};

RectangleD.prototype.getCenterX = function () {
  return this.x + this.width / 2;
};

RectangleD.prototype.getMinX = function () {
  return this.getX();
};

RectangleD.prototype.getMaxX = function () {
  return this.getX() + this.width;
};

RectangleD.prototype.getCenterY = function () {
  return this.y + this.height / 2;
};

RectangleD.prototype.getMinY = function () {
  return this.getY();
};

RectangleD.prototype.getMaxY = function () {
  return this.getY() + this.height;
};

RectangleD.prototype.getWidthHalf = function () {
  return this.width / 2;
};

RectangleD.prototype.getHeightHalf = function () {
  return this.height / 2;
};

module.exports = RectangleD;

/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function UniqueIDGeneretor() {}

UniqueIDGeneretor.lastID = 0;

UniqueIDGeneretor.createID = function (obj) {
  if (UniqueIDGeneretor.isPrimitive(obj)) {
    return obj;
  }
  if (obj.uniqueID != null) {
    return obj.uniqueID;
  }
  obj.uniqueID = UniqueIDGeneretor.getString();
  UniqueIDGeneretor.lastID++;
  return obj.uniqueID;
};

UniqueIDGeneretor.getString = function (id) {
  if (id == null) id = UniqueIDGeneretor.lastID;
  return "Object#" + id + "";
};

UniqueIDGeneretor.isPrimitive = function (arg) {
  var type = typeof arg === "undefined" ? "undefined" : _typeof(arg);
  return arg == null || type != "object" && type != "function";
};

module.exports = UniqueIDGeneretor;

/***/ }),
/* 15 */
/***/ (function(module, exports, __nested_webpack_require_64072__) {

"use strict";


function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var LayoutConstants = __nested_webpack_require_64072__(0);
var LGraphManager = __nested_webpack_require_64072__(6);
var LNode = __nested_webpack_require_64072__(3);
var LEdge = __nested_webpack_require_64072__(1);
var LGraph = __nested_webpack_require_64072__(5);
var PointD = __nested_webpack_require_64072__(4);
var Transform = __nested_webpack_require_64072__(17);
var Emitter = __nested_webpack_require_64072__(27);

function Layout(isRemoteUse) {
  Emitter.call(this);

  //Layout Quality: 0:draft, 1:default, 2:proof
  this.layoutQuality = LayoutConstants.QUALITY;
  //Whether layout should create bendpoints as needed or not
  this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
  //Whether layout should be incremental or not
  this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;
  //Whether we animate from before to after layout node positions
  this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;
  //Whether we animate the layout process or not
  this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;
  //Number iterations that should be done between two successive animations
  this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;
  /**
   * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When
   * they are, both spring and repulsion forces between two leaf nodes can be
   * calculated without the expensive clipping point calculations, resulting
   * in major speed-up.
   */
  this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;
  /**
   * This is used for creation of bendpoints by using dummy nodes and edges.
   * Maps an LEdge to its dummy bendpoint path.
   */
  this.edgeToDummyNodes = new Map();
  this.graphManager = new LGraphManager(this);
  this.isLayoutFinished = false;
  this.isSubLayout = false;
  this.isRemoteUse = false;

  if (isRemoteUse != null) {
    this.isRemoteUse = isRemoteUse;
  }
}

Layout.RANDOM_SEED = 1;

Layout.prototype = Object.create(Emitter.prototype);

Layout.prototype.getGraphManager = function () {
  return this.graphManager;
};

Layout.prototype.getAllNodes = function () {
  return this.graphManager.getAllNodes();
};

Layout.prototype.getAllEdges = function () {
  return this.graphManager.getAllEdges();
};

Layout.prototype.getAllNodesToApplyGravitation = function () {
  return this.graphManager.getAllNodesToApplyGravitation();
};

Layout.prototype.newGraphManager = function () {
  var gm = new LGraphManager(this);
  this.graphManager = gm;
  return gm;
};

Layout.prototype.newGraph = function (vGraph) {
  return new LGraph(null, this.graphManager, vGraph);
};

Layout.prototype.newNode = function (vNode) {
  return new LNode(this.graphManager, vNode);
};

Layout.prototype.newEdge = function (vEdge) {
  return new LEdge(null, null, vEdge);
};

Layout.prototype.checkLayoutSuccess = function () {
  return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge();
};

Layout.prototype.runLayout = function () {
  this.isLayoutFinished = false;

  if (this.tilingPreLayout) {
    this.tilingPreLayout();
  }

  this.initParameters();
  var isLayoutSuccessfull;

  if (this.checkLayoutSuccess()) {
    isLayoutSuccessfull = false;
  } else {
    isLayoutSuccessfull = this.layout();
  }

  if (LayoutConstants.ANIMATE === 'during') {
    // If this is a 'during' layout animation. Layout is not finished yet. 
    // We need to perform these in index.js when layout is really finished.
    return false;
  }

  if (isLayoutSuccessfull) {
    if (!this.isSubLayout) {
      this.doPostLayout();
    }
  }

  if (this.tilingPostLayout) {
    this.tilingPostLayout();
  }

  this.isLayoutFinished = true;

  return isLayoutSuccessfull;
};

/**
 * This method performs the operations required after layout.
 */
Layout.prototype.doPostLayout = function () {
  //assert !isSubLayout : "Should not be called on sub-layout!";
  // Propagate geometric changes to v-level objects
  if (!this.incremental) {
    this.transform();
  }
  this.update();
};

/**
 * This method updates the geometry of the target graph according to
 * calculated layout.
 */
Layout.prototype.update2 = function () {
  // update bend points
  if (this.createBendsAsNeeded) {
    this.createBendpointsFromDummyNodes();

    // reset all edges, since the topology has changed
    this.graphManager.resetAllEdges();
  }

  // perform edge, node and root updates if layout is not called
  // remotely
  if (!this.isRemoteUse) {
    // update all edges
    var edge;
    var allEdges = this.graphManager.getAllEdges();
    for (var i = 0; i < allEdges.length; i++) {
      edge = allEdges[i];
      //      this.update(edge);
    }

    // recursively update nodes
    var node;
    var nodes = this.graphManager.getRoot().getNodes();
    for (var i = 0; i < nodes.length; i++) {
      node = nodes[i];
      //      this.update(node);
    }

    // update root graph
    this.update(this.graphManager.getRoot());
  }
};

Layout.prototype.update = function (obj) {
  if (obj == null) {
    this.update2();
  } else if (obj instanceof LNode) {
    var node = obj;
    if (node.getChild() != null) {
      // since node is compound, recursively update child nodes
      var nodes = node.getChild().getNodes();
      for (var i = 0; i < nodes.length; i++) {
        update(nodes[i]);
      }
    }

    // if the l-level node is associated with a v-level graph object,
    // then it is assumed that the v-level node implements the
    // interface Updatable.
    if (node.vGraphObject != null) {
      // cast to Updatable without any type check
      var vNode = node.vGraphObject;

      // call the update method of the interface
      vNode.update(node);
    }
  } else if (obj instanceof LEdge) {
    var edge = obj;
    // if the l-level edge is associated with a v-level graph object,
    // then it is assumed that the v-level edge implements the
    // interface Updatable.

    if (edge.vGraphObject != null) {
      // cast to Updatable without any type check
      var vEdge = edge.vGraphObject;

      // call the update method of the interface
      vEdge.update(edge);
    }
  } else if (obj instanceof LGraph) {
    var graph = obj;
    // if the l-level graph is associated with a v-level graph object,
    // then it is assumed that the v-level object implements the
    // interface Updatable.

    if (graph.vGraphObject != null) {
      // cast to Updatable without any type check
      var vGraph = graph.vGraphObject;

      // call the update method of the interface
      vGraph.update(graph);
    }
  }
};

/**
 * This method is used to set all layout parameters to default values
 * determined at compile time.
 */
Layout.prototype.initParameters = function () {
  if (!this.isSubLayout) {
    this.layoutQuality = LayoutConstants.QUALITY;
    this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;
    this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;
    this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;
    this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;
    this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
    this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;
  }

  if (this.animationDuringLayout) {
    this.animationOnLayout = false;
  }
};

Layout.prototype.transform = function (newLeftTop) {
  if (newLeftTop == undefined) {
    this.transform(new PointD(0, 0));
  } else {
    // create a transformation object (from Eclipse to layout). When an
    // inverse transform is applied, we get upper-left coordinate of the
    // drawing or the root graph at given input coordinate (some margins
    // already included in calculation of left-top).

    var trans = new Transform();
    var leftTop = this.graphManager.getRoot().updateLeftTop();

    if (leftTop != null) {
      trans.setWorldOrgX(newLeftTop.x);
      trans.setWorldOrgY(newLeftTop.y);

      trans.setDeviceOrgX(leftTop.x);
      trans.setDeviceOrgY(leftTop.y);

      var nodes = this.getAllNodes();
      var node;

      for (var i = 0; i < nodes.length; i++) {
        node = nodes[i];
        node.transform(trans);
      }
    }
  }
};

Layout.prototype.positionNodesRandomly = function (graph) {

  if (graph == undefined) {
    //assert !this.incremental;
    this.positionNodesRandomly(this.getGraphManager().getRoot());
    this.getGraphManager().getRoot().updateBounds(true);
  } else {
    var lNode;
    var childGraph;

    var nodes = graph.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      lNode = nodes[i];
      childGraph = lNode.getChild();

      if (childGraph == null) {
        lNode.scatter();
      } else if (childGraph.getNodes().length == 0) {
        lNode.scatter();
      } else {
        this.positionNodesRandomly(childGraph);
        lNode.updateBounds();
      }
    }
  }
};

/**
 * This method returns a list of trees where each tree is represented as a
 * list of l-nodes. The method returns a list of size 0 when:
 * - The graph is not flat or
 * - One of the component(s) of the graph is not a tree.
 */
Layout.prototype.getFlatForest = function () {
  var flatForest = [];
  var isForest = true;

  // Quick reference for all nodes in the graph manager associated with
  // this layout. The list should not be changed.
  var allNodes = this.graphManager.getRoot().getNodes();

  // First be sure that the graph is flat
  var isFlat = true;

  for (var i = 0; i < allNodes.length; i++) {
    if (allNodes[i].getChild() != null) {
      isFlat = false;
    }
  }

  // Return empty forest if the graph is not flat.
  if (!isFlat) {
    return flatForest;
  }

  // Run BFS for each component of the graph.

  var visited = new Set();
  var toBeVisited = [];
  var parents = new Map();
  var unProcessedNodes = [];

  unProcessedNodes = unProcessedNodes.concat(allNodes);

  // Each iteration of this loop finds a component of the graph and
  // decides whether it is a tree or not. If it is a tree, adds it to the
  // forest and continued with the next component.

  while (unProcessedNodes.length > 0 && isForest) {
    toBeVisited.push(unProcessedNodes[0]);

    // Start the BFS. Each iteration of this loop visits a node in a
    // BFS manner.
    while (toBeVisited.length > 0 && isForest) {
      //pool operation
      var currentNode = toBeVisited[0];
      toBeVisited.splice(0, 1);
      visited.add(currentNode);

      // Traverse all neighbors of this node
      var neighborEdges = currentNode.getEdges();

      for (var i = 0; i < neighborEdges.length; i++) {
        var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode);

        // If BFS is not growing from this neighbor.
        if (parents.get(currentNode) != currentNeighbor) {
          // We haven't previously visited this neighbor.
          if (!visited.has(currentNeighbor)) {
            toBeVisited.push(currentNeighbor);
            parents.set(currentNeighbor, currentNode);
          }
          // Since we have previously visited this neighbor and
          // this neighbor is not parent of currentNode, given
          // graph contains a component that is not tree, hence
          // it is not a forest.
          else {
              isForest = false;
              break;
            }
        }
      }
    }

    // The graph contains a component that is not a tree. Empty
    // previously found trees. The method will end.
    if (!isForest) {
      flatForest = [];
    }
    // Save currently visited nodes as a tree in our forest. Reset
    // visited and parents lists. Continue with the next component of
    // the graph, if any.
    else {
        var temp = [].concat(_toConsumableArray(visited));
        flatForest.push(temp);
        //flatForest = flatForest.concat(temp);
        //unProcessedNodes.removeAll(visited);
        for (var i = 0; i < temp.length; i++) {
          var value = temp[i];
          var index = unProcessedNodes.indexOf(value);
          if (index > -1) {
            unProcessedNodes.splice(index, 1);
          }
        }
        visited = new Set();
        parents = new Map();
      }
  }

  return flatForest;
};

/**
 * This method creates dummy nodes (an l-level node with minimal dimensions)
 * for the given edge (one per bendpoint). The existing l-level structure
 * is updated accordingly.
 */
Layout.prototype.createDummyNodesForBendpoints = function (edge) {
  var dummyNodes = [];
  var prev = edge.source;

  var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target);

  for (var i = 0; i < edge.bendpoints.length; i++) {
    // create new dummy node
    var dummyNode = this.newNode(null);
    dummyNode.setRect(new Point(0, 0), new Dimension(1, 1));

    graph.add(dummyNode);

    // create new dummy edge between prev and dummy node
    var dummyEdge = this.newEdge(null);
    this.graphManager.add(dummyEdge, prev, dummyNode);

    dummyNodes.add(dummyNode);
    prev = dummyNode;
  }

  var dummyEdge = this.newEdge(null);
  this.graphManager.add(dummyEdge, prev, edge.target);

  this.edgeToDummyNodes.set(edge, dummyNodes);

  // remove real edge from graph manager if it is inter-graph
  if (edge.isInterGraph()) {
    this.graphManager.remove(edge);
  }
  // else, remove the edge from the current graph
  else {
      graph.remove(edge);
    }

  return dummyNodes;
};

/**
 * This method creates bendpoints for edges from the dummy nodes
 * at l-level.
 */
Layout.prototype.createBendpointsFromDummyNodes = function () {
  var edges = [];
  edges = edges.concat(this.graphManager.getAllEdges());
  edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges);

  for (var k = 0; k < edges.length; k++) {
    var lEdge = edges[k];

    if (lEdge.bendpoints.length > 0) {
      var path = this.edgeToDummyNodes.get(lEdge);

      for (var i = 0; i < path.length; i++) {
        var dummyNode = path[i];
        var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY());

        // update bendpoint's location according to dummy node
        var ebp = lEdge.bendpoints.get(i);
        ebp.x = p.x;
        ebp.y = p.y;

        // remove the dummy node, dummy edges incident with this
        // dummy node is also removed (within the remove method)
        dummyNode.getOwner().remove(dummyNode);
      }

      // add the real edge to graph
      this.graphManager.add(lEdge, lEdge.source, lEdge.target);
    }
  }
};

Layout.transform = function (sliderValue, defaultValue, minDiv, maxMul) {
  if (minDiv != undefined && maxMul != undefined) {
    var value = defaultValue;

    if (sliderValue <= 50) {
      var minValue = defaultValue / minDiv;
      value -= (defaultValue - minValue) / 50 * (50 - sliderValue);
    } else {
      var maxValue = defaultValue * maxMul;
      value += (maxValue - defaultValue) / 50 * (sliderValue - 50);
    }

    return value;
  } else {
    var a, b;

    if (sliderValue <= 50) {
      a = 9.0 * defaultValue / 500.0;
      b = defaultValue / 10.0;
    } else {
      a = 9.0 * defaultValue / 50.0;
      b = -8 * defaultValue;
    }

    return a * sliderValue + b;
  }
};

/**
 * This method finds and returns the center of the given nodes, assuming
 * that the given nodes form a tree in themselves.
 */
Layout.findCenterOfTree = function (nodes) {
  var list = [];
  list = list.concat(nodes);

  var removedNodes = [];
  var remainingDegrees = new Map();
  var foundCenter = false;
  var centerNode = null;

  if (list.length == 1 || list.length == 2) {
    foundCenter = true;
    centerNode = list[0];
  }

  for (var i = 0; i < list.length; i++) {
    var node = list[i];
    var degree = node.getNeighborsList().size;
    remainingDegrees.set(node, node.getNeighborsList().size);

    if (degree == 1) {
      removedNodes.push(node);
    }
  }

  var tempList = [];
  tempList = tempList.concat(removedNodes);

  while (!foundCenter) {
    var tempList2 = [];
    tempList2 = tempList2.concat(tempList);
    tempList = [];

    for (var i = 0; i < list.length; i++) {
      var node = list[i];

      var index = list.indexOf(node);
      if (index >= 0) {
        list.splice(index, 1);
      }

      var neighbours = node.getNeighborsList();

      neighbours.forEach(function (neighbour) {
        if (removedNodes.indexOf(neighbour) < 0) {
          var otherDegree = remainingDegrees.get(neighbour);
          var newDegree = otherDegree - 1;

          if (newDegree == 1) {
            tempList.push(neighbour);
          }

          remainingDegrees.set(neighbour, newDegree);
        }
      });
    }

    removedNodes = removedNodes.concat(tempList);

    if (list.length == 1 || list.length == 2) {
      foundCenter = true;
      centerNode = list[0];
    }
  }

  return centerNode;
};

/**
 * During the coarsening process, this layout may be referenced by two graph managers
 * this setter function grants access to change the currently being used graph manager
 */
Layout.prototype.setGraphManager = function (gm) {
  this.graphManager = gm;
};

module.exports = Layout;

/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function RandomSeed() {}
// adapted from: https://stackoverflow.com/a/19303725
RandomSeed.seed = 1;
RandomSeed.x = 0;

RandomSeed.nextDouble = function () {
  RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000;
  return RandomSeed.x - Math.floor(RandomSeed.x);
};

module.exports = RandomSeed;

/***/ }),
/* 17 */
/***/ (function(module, exports, __nested_webpack_require_81860__) {

"use strict";


var PointD = __nested_webpack_require_81860__(4);

function Transform(x, y) {
  this.lworldOrgX = 0.0;
  this.lworldOrgY = 0.0;
  this.ldeviceOrgX = 0.0;
  this.ldeviceOrgY = 0.0;
  this.lworldExtX = 1.0;
  this.lworldExtY = 1.0;
  this.ldeviceExtX = 1.0;
  this.ldeviceExtY = 1.0;
}

Transform.prototype.getWorldOrgX = function () {
  return this.lworldOrgX;
};

Transform.prototype.setWorldOrgX = function (wox) {
  this.lworldOrgX = wox;
};

Transform.prototype.getWorldOrgY = function () {
  return this.lworldOrgY;
};

Transform.prototype.setWorldOrgY = function (woy) {
  this.lworldOrgY = woy;
};

Transform.prototype.getWorldExtX = function () {
  return this.lworldExtX;
};

Transform.prototype.setWorldExtX = function (wex) {
  this.lworldExtX = wex;
};

Transform.prototype.getWorldExtY = function () {
  return this.lworldExtY;
};

Transform.prototype.setWorldExtY = function (wey) {
  this.lworldExtY = wey;
};

/* Device related */

Transform.prototype.getDeviceOrgX = function () {
  return this.ldeviceOrgX;
};

Transform.prototype.setDeviceOrgX = function (dox) {
  this.ldeviceOrgX = dox;
};

Transform.prototype.getDeviceOrgY = function () {
  return this.ldeviceOrgY;
};

Transform.prototype.setDeviceOrgY = function (doy) {
  this.ldeviceOrgY = doy;
};

Transform.prototype.getDeviceExtX = function () {
  return this.ldeviceExtX;
};

Transform.prototype.setDeviceExtX = function (dex) {
  this.ldeviceExtX = dex;
};

Transform.prototype.getDeviceExtY = function () {
  return this.ldeviceExtY;
};

Transform.prototype.setDeviceExtY = function (dey) {
  this.ldeviceExtY = dey;
};

Transform.prototype.transformX = function (x) {
  var xDevice = 0.0;
  var worldExtX = this.lworldExtX;
  if (worldExtX != 0.0) {
    xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX;
  }

  return xDevice;
};

Transform.prototype.transformY = function (y) {
  var yDevice = 0.0;
  var worldExtY = this.lworldExtY;
  if (worldExtY != 0.0) {
    yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY;
  }

  return yDevice;
};

Transform.prototype.inverseTransformX = function (x) {
  var xWorld = 0.0;
  var deviceExtX = this.ldeviceExtX;
  if (deviceExtX != 0.0) {
    xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX;
  }

  return xWorld;
};

Transform.prototype.inverseTransformY = function (y) {
  var yWorld = 0.0;
  var deviceExtY = this.ldeviceExtY;
  if (deviceExtY != 0.0) {
    yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY;
  }
  return yWorld;
};

Transform.prototype.inverseTransformPoint = function (inPoint) {
  var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y));
  return outPoint;
};

module.exports = Transform;

/***/ }),
/* 18 */
/***/ (function(module, exports, __nested_webpack_require_84747__) {

"use strict";


function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var Layout = __nested_webpack_require_84747__(15);
var FDLayoutConstants = __nested_webpack_require_84747__(7);
var LayoutConstants = __nested_webpack_require_84747__(0);
var IGeometry = __nested_webpack_require_84747__(8);
var IMath = __nested_webpack_require_84747__(9);

function FDLayout() {
  Layout.call(this);

  this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;
  this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
  this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;
  this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;
  this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;
  this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;
  this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;
  this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;
  this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100;
  this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
  this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
  this.totalDisplacement = 0.0;
  this.oldTotalDisplacement = 0.0;
  this.maxIterations = FDLayoutConstants.MAX_ITERATIONS;
}

FDLayout.prototype = Object.create(Layout.prototype);

for (var prop in Layout) {
  FDLayout[prop] = Layout[prop];
}

FDLayout.prototype.initParameters = function () {
  Layout.prototype.initParameters.call(this, arguments);

  this.totalIterations = 0;
  this.notAnimatedIterations = 0;

  this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION;

  this.grid = [];
};

FDLayout.prototype.calcIdealEdgeLengths = function () {
  var edge;
  var lcaDepth;
  var source;
  var target;
  var sizeOfSourceInLca;
  var sizeOfTargetInLca;

  var allEdges = this.getGraphManager().getAllEdges();
  for (var i = 0; i < allEdges.length; i++) {
    edge = allEdges[i];

    edge.idealLength = this.idealEdgeLength;

    if (edge.isInterGraph) {
      source = edge.getSource();
      target = edge.getTarget();

      sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize();
      sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize();

      if (this.useSmartIdealEdgeLengthCalculation) {
        edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE;
      }

      lcaDepth = edge.getLca().getInclusionTreeDepth();

      edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth);
    }
  }
};

FDLayout.prototype.initSpringEmbedder = function () {

  var s = this.getAllNodes().length;
  if (this.incremental) {
    if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {
      this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));
    }
    this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL;
  } else {
    if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {
      this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));
    } else {
      this.coolingFactor = 1.0;
    }
    this.initialCoolingFactor = this.coolingFactor;
    this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT;
  }

  this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations);

  this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length;

  this.repulsionRange = this.calcRepulsionRange();
};

FDLayout.prototype.calcSpringForces = function () {
  var lEdges = this.getAllEdges();
  var edge;

  for (var i = 0; i < lEdges.length; i++) {
    edge = lEdges[i];

    this.calcSpringForce(edge, edge.idealLength);
  }
};

FDLayout.prototype.calcRepulsionForces = function () {
  var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  var i, j;
  var nodeA, nodeB;
  var lNodes = this.getAllNodes();
  var processedNodeSet;

  if (this.useFRGridVariant) {
    if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) {
      this.updateGrid();
    }

    processedNodeSet = new Set();

    // calculate repulsion forces between each nodes and its surrounding
    for (i = 0; i < lNodes.length; i++) {
      nodeA = lNodes[i];
      this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate);
      processedNodeSet.add(nodeA);
    }
  } else {
    for (i = 0; i < lNodes.length; i++) {
      nodeA = lNodes[i];

      for (j = i + 1; j < lNodes.length; j++) {
        nodeB = lNodes[j];

        // If both nodes are not members of the same graph, skip.
        if (nodeA.getOwner() != nodeB.getOwner()) {
          continue;
        }

        this.calcRepulsionForce(nodeA, nodeB);
      }
    }
  }
};

FDLayout.prototype.calcGravitationalForces = function () {
  var node;
  var lNodes = this.getAllNodesToApplyGravitation();

  for (var i = 0; i < lNodes.length; i++) {
    node = lNodes[i];
    this.calcGravitationalForce(node);
  }
};

FDLayout.prototype.moveNodes = function () {
  var lNodes = this.getAllNodes();
  var node;

  for (var i = 0; i < lNodes.length; i++) {
    node = lNodes[i];
    node.move();
  }
};

FDLayout.prototype.calcSpringForce = function (edge, idealLength) {
  var sourceNode = edge.getSource();
  var targetNode = edge.getTarget();

  var length;
  var springForce;
  var springForceX;
  var springForceY;

  // Update edge length
  if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) {
    edge.updateLengthSimple();
  } else {
    edge.updateLength();

    if (edge.isOverlapingSourceAndTarget) {
      return;
    }
  }

  length = edge.getLength();

  if (length == 0) return;

  // Calculate spring forces
  springForce = this.springConstant * (length - idealLength);

  // Project force onto x and y axes
  springForceX = springForce * (edge.lengthX / length);
  springForceY = springForce * (edge.lengthY / length);

  // Apply forces on the end nodes
  sourceNode.springForceX += springForceX;
  sourceNode.springForceY += springForceY;
  targetNode.springForceX -= springForceX;
  targetNode.springForceY -= springForceY;
};

FDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) {
  var rectA = nodeA.getRect();
  var rectB = nodeB.getRect();
  var overlapAmount = new Array(2);
  var clipPoints = new Array(4);
  var distanceX;
  var distanceY;
  var distanceSquared;
  var distance;
  var repulsionForce;
  var repulsionForceX;
  var repulsionForceY;

  if (rectA.intersects(rectB)) // two nodes overlap
    {
      // calculate separation amount in x and y directions
      IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0);

      repulsionForceX = 2 * overlapAmount[0];
      repulsionForceY = 2 * overlapAmount[1];

      var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren);

      // Apply forces on the two nodes
      nodeA.repulsionForceX -= childrenConstant * repulsionForceX;
      nodeA.repulsionForceY -= childrenConstant * repulsionForceY;
      nodeB.repulsionForceX += childrenConstant * repulsionForceX;
      nodeB.repulsionForceY += childrenConstant * repulsionForceY;
    } else // no overlap
    {
      // calculate distance

      if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers
        {
          distanceX = rectB.getCenterX() - rectA.getCenterX();
          distanceY = rectB.getCenterY() - rectA.getCenterY();
        } else // use clipping points
        {
          IGeometry.getIntersection(rectA, rectB, clipPoints);

          distanceX = clipPoints[2] - clipPoints[0];
          distanceY = clipPoints[3] - clipPoints[1];
        }

      // No repulsion range. FR grid variant should take care of this.
      if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) {
        distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST;
      }

      if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) {
        distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST;
      }

      distanceSquared = distanceX * distanceX + distanceY * distanceY;
      distance = Math.sqrt(distanceSquared);

      repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared;

      // Project force onto x and y axes
      repulsionForceX = repulsionForce * distanceX / distance;
      repulsionForceY = repulsionForce * distanceY / distance;

      // Apply forces on the two nodes    
      nodeA.repulsionForceX -= repulsionForceX;
      nodeA.repulsionForceY -= repulsionForceY;
      nodeB.repulsionForceX += repulsionForceX;
      nodeB.repulsionForceY += repulsionForceY;
    }
};

FDLayout.prototype.calcGravitationalForce = function (node) {
  var ownerGraph;
  var ownerCenterX;
  var ownerCenterY;
  var distanceX;
  var distanceY;
  var absDistanceX;
  var absDistanceY;
  var estimatedSize;
  ownerGraph = node.getOwner();

  ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2;
  ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2;
  distanceX = node.getCenterX() - ownerCenterX;
  distanceY = node.getCenterY() - ownerCenterY;
  absDistanceX = Math.abs(distanceX) + node.getWidth() / 2;
  absDistanceY = Math.abs(distanceY) + node.getHeight() / 2;

  if (node.getOwner() == this.graphManager.getRoot()) // in the root graph
    {
      estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor;

      if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {
        node.gravitationForceX = -this.gravityConstant * distanceX;
        node.gravitationForceY = -this.gravityConstant * distanceY;
      }
    } else // inside a compound
    {
      estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor;

      if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {
        node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant;
        node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant;
      }
    }
};

FDLayout.prototype.isConverged = function () {
  var converged;
  var oscilating = false;

  if (this.totalIterations > this.maxIterations / 3) {
    oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2;
  }

  converged = this.totalDisplacement < this.totalDisplacementThreshold;

  this.oldTotalDisplacement = this.totalDisplacement;

  return converged || oscilating;
};

FDLayout.prototype.animate = function () {
  if (this.animationDuringLayout && !this.isSubLayout) {
    if (this.notAnimatedIterations == this.animationPeriod) {
      this.update();
      this.notAnimatedIterations = 0;
    } else {
      this.notAnimatedIterations++;
    }
  }
};

//This method calculates the number of children (weight) for all nodes
FDLayout.prototype.calcNoOfChildrenForAllNodes = function () {
  var node;
  var allNodes = this.graphManager.getAllNodes();

  for (var i = 0; i < allNodes.length; i++) {
    node = allNodes[i];
    node.noOfChildren = node.getNoOfChildren();
  }
};

// -----------------------------------------------------------------------------
// Section: FR-Grid Variant Repulsion Force Calculation
// -----------------------------------------------------------------------------

FDLayout.prototype.calcGrid = function (graph) {

  var sizeX = 0;
  var sizeY = 0;

  sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange));
  sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange));

  var grid = new Array(sizeX);

  for (var i = 0; i < sizeX; i++) {
    grid[i] = new Array(sizeY);
  }

  for (var i = 0; i < sizeX; i++) {
    for (var j = 0; j < sizeY; j++) {
      grid[i][j] = new Array();
    }
  }

  return grid;
};

FDLayout.prototype.addNodeToGrid = function (v, left, top) {

  var startX = 0;
  var finishX = 0;
  var startY = 0;
  var finishY = 0;

  startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange));
  finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange));
  startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange));
  finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange));

  for (var i = startX; i <= finishX; i++) {
    for (var j = startY; j <= finishY; j++) {
      this.grid[i][j].push(v);
      v.setGridCoordinates(startX, finishX, startY, finishY);
    }
  }
};

FDLayout.prototype.updateGrid = function () {
  var i;
  var nodeA;
  var lNodes = this.getAllNodes();

  this.grid = this.calcGrid(this.graphManager.getRoot());

  // put all nodes to proper grid cells
  for (i = 0; i < lNodes.length; i++) {
    nodeA = lNodes[i];
    this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop());
  }
};

FDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) {

  if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) {
    var surrounding = new Set();
    nodeA.surrounding = new Array();
    var nodeB;
    var grid = this.grid;

    for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) {
      for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) {
        if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) {
          for (var k = 0; k < grid[i][j].length; k++) {
            nodeB = grid[i][j][k];

            // If both nodes are not members of the same graph, 
            // or both nodes are the same, skip.
            if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) {
              continue;
            }

            // check if the repulsion force between
            // nodeA and nodeB has already been calculated
            if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) {
              var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2);
              var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2);

              // if the distance between nodeA and nodeB 
              // is less then calculation range
              if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) {
                //then add nodeB to surrounding of nodeA
                surrounding.add(nodeB);
              }
            }
          }
        }
      }
    }

    nodeA.surrounding = [].concat(_toConsumableArray(surrounding));
  }
  for (i = 0; i < nodeA.surrounding.length; i++) {
    this.calcRepulsionForce(nodeA, nodeA.surrounding[i]);
  }
};

FDLayout.prototype.calcRepulsionRange = function () {
  return 0.0;
};

module.exports = FDLayout;

/***/ }),
/* 19 */
/***/ (function(module, exports, __nested_webpack_require_100902__) {

"use strict";


var LEdge = __nested_webpack_require_100902__(1);
var FDLayoutConstants = __nested_webpack_require_100902__(7);

function FDLayoutEdge(source, target, vEdge) {
  LEdge.call(this, source, target, vEdge);
  this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
}

FDLayoutEdge.prototype = Object.create(LEdge.prototype);

for (var prop in LEdge) {
  FDLayoutEdge[prop] = LEdge[prop];
}

module.exports = FDLayoutEdge;

/***/ }),
/* 20 */
/***/ (function(module, exports, __nested_webpack_require_101387__) {

"use strict";


var LNode = __nested_webpack_require_101387__(3);

function FDLayoutNode(gm, loc, size, vNode) {
  // alternative constructor is handled inside LNode
  LNode.call(this, gm, loc, size, vNode);
  //Spring, repulsion and gravitational forces acting on this node
  this.springForceX = 0;
  this.springForceY = 0;
  this.repulsionForceX = 0;
  this.repulsionForceY = 0;
  this.gravitationForceX = 0;
  this.gravitationForceY = 0;
  //Amount by which this node is to be moved in this iteration
  this.displacementX = 0;
  this.displacementY = 0;

  //Start and finish grid coordinates that this node is fallen into
  this.startX = 0;
  this.finishX = 0;
  this.startY = 0;
  this.finishY = 0;

  //Geometric neighbors of this node
  this.surrounding = [];
}

FDLayoutNode.prototype = Object.create(LNode.prototype);

for (var prop in LNode) {
  FDLayoutNode[prop] = LNode[prop];
}

FDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) {
  this.startX = _startX;
  this.finishX = _finishX;
  this.startY = _startY;
  this.finishY = _finishY;
};

module.exports = FDLayoutNode;

/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function DimensionD(width, height) {
  this.width = 0;
  this.height = 0;
  if (width !== null && height !== null) {
    this.height = height;
    this.width = width;
  }
}

DimensionD.prototype.getWidth = function () {
  return this.width;
};

DimensionD.prototype.setWidth = function (width) {
  this.width = width;
};

DimensionD.prototype.getHeight = function () {
  return this.height;
};

DimensionD.prototype.setHeight = function (height) {
  this.height = height;
};

module.exports = DimensionD;

/***/ }),
/* 22 */
/***/ (function(module, exports, __nested_webpack_require_103173__) {

"use strict";


var UniqueIDGeneretor = __nested_webpack_require_103173__(14);

function HashMap() {
  this.map = {};
  this.keys = [];
}

HashMap.prototype.put = function (key, value) {
  var theId = UniqueIDGeneretor.createID(key);
  if (!this.contains(theId)) {
    this.map[theId] = value;
    this.keys.push(key);
  }
};

HashMap.prototype.contains = function (key) {
  var theId = UniqueIDGeneretor.createID(key);
  return this.map[key] != null;
};

HashMap.prototype.get = function (key) {
  var theId = UniqueIDGeneretor.createID(key);
  return this.map[theId];
};

HashMap.prototype.keySet = function () {
  return this.keys;
};

module.exports = HashMap;

/***/ }),
/* 23 */
/***/ (function(module, exports, __nested_webpack_require_103901__) {

"use strict";


var UniqueIDGeneretor = __nested_webpack_require_103901__(14);

function HashSet() {
  this.set = {};
}
;

HashSet.prototype.add = function (obj) {
  var theId = UniqueIDGeneretor.createID(obj);
  if (!this.contains(theId)) this.set[theId] = obj;
};

HashSet.prototype.remove = function (obj) {
  delete this.set[UniqueIDGeneretor.createID(obj)];
};

HashSet.prototype.clear = function () {
  this.set = {};
};

HashSet.prototype.contains = function (obj) {
  return this.set[UniqueIDGeneretor.createID(obj)] == obj;
};

HashSet.prototype.isEmpty = function () {
  return this.size() === 0;
};

HashSet.prototype.size = function () {
  return Object.keys(this.set).length;
};

//concats this.set to the given list
HashSet.prototype.addAllTo = function (list) {
  var keys = Object.keys(this.set);
  var length = keys.length;
  for (var i = 0; i < length; i++) {
    list.push(this.set[keys[i]]);
  }
};

HashSet.prototype.size = function () {
  return Object.keys(this.set).length;
};

HashSet.prototype.addAll = function (list) {
  var s = list.length;
  for (var i = 0; i < s; i++) {
    var v = list[i];
    this.add(v);
  }
};

module.exports = HashSet;

/***/ }),
/* 24 */
/***/ (function(module, exports, __nested_webpack_require_105138__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * A classic Quicksort algorithm with Hoare's partition
 * - Works also on LinkedList objects
 *
 * Copyright: i-Vis Research Group, Bilkent University, 2007 - present
 */

var LinkedList = __nested_webpack_require_105138__(11);

var Quicksort = function () {
    function Quicksort(A, compareFunction) {
        _classCallCheck(this, Quicksort);

        if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction;

        var length = void 0;
        if (A instanceof LinkedList) length = A.size();else length = A.length;

        this._quicksort(A, 0, length - 1);
    }

    _createClass(Quicksort, [{
        key: '_quicksort',
        value: function _quicksort(A, p, r) {
            if (p < r) {
                var q = this._partition(A, p, r);
                this._quicksort(A, p, q);
                this._quicksort(A, q + 1, r);
            }
        }
    }, {
        key: '_partition',
        value: function _partition(A, p, r) {
            var x = this._get(A, p);
            var i = p;
            var j = r;
            while (true) {
                while (this.compareFunction(x, this._get(A, j))) {
                    j--;
                }while (this.compareFunction(this._get(A, i), x)) {
                    i++;
                }if (i < j) {
                    this._swap(A, i, j);
                    i++;
                    j--;
                } else return j;
            }
        }
    }, {
        key: '_get',
        value: function _get(object, index) {
            if (object instanceof LinkedList) return object.get_object_at(index);else return object[index];
        }
    }, {
        key: '_set',
        value: function _set(object, index, value) {
            if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value;
        }
    }, {
        key: '_swap',
        value: function _swap(A, i, j) {
            var temp = this._get(A, i);
            this._set(A, i, this._get(A, j));
            this._set(A, j, temp);
        }
    }, {
        key: '_defaultCompareFunction',
        value: function _defaultCompareFunction(a, b) {
            return b > a;
        }
    }]);

    return Quicksort;
}();

module.exports = Quicksort;

/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 *   Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string
 *   sequences by S.B.Needleman and C.D.Wunsch (1970).
 *
 *   Aside from the inputs, you can assign the scores for,
 *   - Match: The two characters at the current index are same.
 *   - Mismatch: The two characters at the current index are different.
 *   - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string.
 */

var NeedlemanWunsch = function () {
    function NeedlemanWunsch(sequence1, sequence2) {
        var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
        var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;
        var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;

        _classCallCheck(this, NeedlemanWunsch);

        this.sequence1 = sequence1;
        this.sequence2 = sequence2;
        this.match_score = match_score;
        this.mismatch_penalty = mismatch_penalty;
        this.gap_penalty = gap_penalty;

        // Just the remove redundancy
        this.iMax = sequence1.length + 1;
        this.jMax = sequence2.length + 1;

        // Grid matrix of scores
        this.grid = new Array(this.iMax);
        for (var i = 0; i < this.iMax; i++) {
            this.grid[i] = new Array(this.jMax);

            for (var j = 0; j < this.jMax; j++) {
                this.grid[i][j] = 0;
            }
        }

        // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions)
        this.tracebackGrid = new Array(this.iMax);
        for (var _i = 0; _i < this.iMax; _i++) {
            this.tracebackGrid[_i] = new Array(this.jMax);

            for (var _j = 0; _j < this.jMax; _j++) {
                this.tracebackGrid[_i][_j] = [null, null, null];
            }
        }

        // The aligned sequences (return multiple possibilities)
        this.alignments = [];

        // Final alignment score
        this.score = -1;

        // Calculate scores and tracebacks
        this.computeGrids();
    }

    _createClass(NeedlemanWunsch, [{
        key: "getScore",
        value: function getScore() {
            return this.score;
        }
    }, {
        key: "getAlignments",
        value: function getAlignments() {
            return this.alignments;
        }

        // Main dynamic programming procedure

    }, {
        key: "computeGrids",
        value: function computeGrids() {
            // Fill in the first row
            for (var j = 1; j < this.jMax; j++) {
                this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty;
                this.tracebackGrid[0][j] = [false, false, true];
            }

            // Fill in the first column
            for (var i = 1; i < this.iMax; i++) {
                this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty;
                this.tracebackGrid[i][0] = [false, true, false];
            }

            // Fill the rest of the grid
            for (var _i2 = 1; _i2 < this.iMax; _i2++) {
                for (var _j2 = 1; _j2 < this.jMax; _j2++) {
                    // Find the max score(s) among [`Diag`, `Up`, `Left`]
                    var diag = void 0;
                    if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty;

                    var up = this.grid[_i2 - 1][_j2] + this.gap_penalty;
                    var left = this.grid[_i2][_j2 - 1] + this.gap_penalty;

                    // If there exists multiple max values, capture them for multiple paths
                    var maxOf = [diag, up, left];
                    var indices = this.arrayAllMaxIndexes(maxOf);

                    // Update Grids
                    this.grid[_i2][_j2] = maxOf[indices[0]];
                    this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)];
                }
            }

            // Update alignment score
            this.score = this.grid[this.iMax - 1][this.jMax - 1];
        }

        // Gets all possible valid sequence combinations

    }, {
        key: "alignmentTraceback",
        value: function alignmentTraceback() {
            var inProcessAlignments = [];

            inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length],
                seq1: "",
                seq2: ""
            });

            while (inProcessAlignments[0]) {
                var current = inProcessAlignments[0];
                var directions = this.tracebackGrid[current.pos[0]][current.pos[1]];

                if (directions[0]) {
                    inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1],
                        seq1: this.sequence1[current.pos[0] - 1] + current.seq1,
                        seq2: this.sequence2[current.pos[1] - 1] + current.seq2
                    });
                }
                if (directions[1]) {
                    inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]],
                        seq1: this.sequence1[current.pos[0] - 1] + current.seq1,
                        seq2: '-' + current.seq2
                    });
                }
                if (directions[2]) {
                    inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1],
                        seq1: '-' + current.seq1,
                        seq2: this.sequence2[current.pos[1] - 1] + current.seq2
                    });
                }

                if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1,
                    sequence2: current.seq2
                });

                inProcessAlignments.shift();
            }

            return this.alignments;
        }

        // Helper Functions

    }, {
        key: "getAllIndexes",
        value: function getAllIndexes(arr, val) {
            var indexes = [],
                i = -1;
            while ((i = arr.indexOf(val, i + 1)) !== -1) {
                indexes.push(i);
            }
            return indexes;
        }
    }, {
        key: "arrayAllMaxIndexes",
        value: function arrayAllMaxIndexes(array) {
            return this.getAllIndexes(array, Math.max.apply(null, array));
        }
    }]);

    return NeedlemanWunsch;
}();

module.exports = NeedlemanWunsch;

/***/ }),
/* 26 */
/***/ (function(module, exports, __nested_webpack_require_115611__) {

"use strict";


var layoutBase = function layoutBase() {
  return;
};

layoutBase.FDLayout = __nested_webpack_require_115611__(18);
layoutBase.FDLayoutConstants = __nested_webpack_require_115611__(7);
layoutBase.FDLayoutEdge = __nested_webpack_require_115611__(19);
layoutBase.FDLayoutNode = __nested_webpack_require_115611__(20);
layoutBase.DimensionD = __nested_webpack_require_115611__(21);
layoutBase.HashMap = __nested_webpack_require_115611__(22);
layoutBase.HashSet = __nested_webpack_require_115611__(23);
layoutBase.IGeometry = __nested_webpack_require_115611__(8);
layoutBase.IMath = __nested_webpack_require_115611__(9);
layoutBase.Integer = __nested_webpack_require_115611__(10);
layoutBase.Point = __nested_webpack_require_115611__(12);
layoutBase.PointD = __nested_webpack_require_115611__(4);
layoutBase.RandomSeed = __nested_webpack_require_115611__(16);
layoutBase.RectangleD = __nested_webpack_require_115611__(13);
layoutBase.Transform = __nested_webpack_require_115611__(17);
layoutBase.UniqueIDGeneretor = __nested_webpack_require_115611__(14);
layoutBase.Quicksort = __nested_webpack_require_115611__(24);
layoutBase.LinkedList = __nested_webpack_require_115611__(11);
layoutBase.LGraphObject = __nested_webpack_require_115611__(2);
layoutBase.LGraph = __nested_webpack_require_115611__(5);
layoutBase.LEdge = __nested_webpack_require_115611__(1);
layoutBase.LGraphManager = __nested_webpack_require_115611__(6);
layoutBase.LNode = __nested_webpack_require_115611__(3);
layoutBase.Layout = __nested_webpack_require_115611__(15);
layoutBase.LayoutConstants = __nested_webpack_require_115611__(0);
layoutBase.NeedlemanWunsch = __nested_webpack_require_115611__(25);

module.exports = layoutBase;

/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function Emitter() {
  this.listeners = [];
}

var p = Emitter.prototype;

p.addListener = function (event, callback) {
  this.listeners.push({
    event: event,
    callback: callback
  });
};

p.removeListener = function (event, callback) {
  for (var i = this.listeners.length; i >= 0; i--) {
    var l = this.listeners[i];

    if (l.event === event && l.callback === callback) {
      this.listeners.splice(i, 1);
    }
  }
};

p.emit = function (event, data) {
  for (var i = 0; i < this.listeners.length; i++) {
    var l = this.listeners[i];

    if (event === l.event) {
      l.callback(data);
    }
  }
};

module.exports = Emitter;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 47724:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   diagram: () => (/* binding */ diagram)
/* harmony export */ });
/* harmony import */ var _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(87115);
/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(59373);
/* harmony import */ var cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(71377);
/* harmony import */ var cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14607);
/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(91619);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(12281);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(7201);
/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(27484);
/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(dayjs__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(17967);
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(20683);
/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(70277);
/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(45625);
/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(39354);
/* harmony import */ var dagre_d3_es__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(91518);
/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(59542);
/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(10285);
/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(28734);
/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12__);
























var parser = function() {
  var o = function(k, v, o2, l) {
    for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v)
      ;
    return o2;
  }, $V0 = [1, 4], $V1 = [1, 13], $V2 = [1, 12], $V3 = [1, 15], $V4 = [1, 16], $V5 = [1, 20], $V6 = [1, 19], $V7 = [6, 7, 8], $V8 = [1, 26], $V9 = [1, 24], $Va = [1, 25], $Vb = [6, 7, 11], $Vc = [1, 6, 13, 15, 16, 19, 22], $Vd = [1, 33], $Ve = [1, 34], $Vf = [1, 6, 7, 11, 13, 15, 16, 19, 22];
  var parser2 = {
    trace: function trace() {
    },
    yy: {},
    symbols_: { "error": 2, "start": 3, "mindMap": 4, "spaceLines": 5, "SPACELINE": 6, "NL": 7, "MINDMAP": 8, "document": 9, "stop": 10, "EOF": 11, "statement": 12, "SPACELIST": 13, "node": 14, "ICON": 15, "CLASS": 16, "nodeWithId": 17, "nodeWithoutId": 18, "NODE_DSTART": 19, "NODE_DESCR": 20, "NODE_DEND": 21, "NODE_ID": 22, "$accept": 0, "$end": 1 },
    terminals_: { 2: "error", 6: "SPACELINE", 7: "NL", 8: "MINDMAP", 11: "EOF", 13: "SPACELIST", 15: "ICON", 16: "CLASS", 19: "NODE_DSTART", 20: "NODE_DESCR", 21: "NODE_DEND", 22: "NODE_ID" },
    productions_: [0, [3, 1], [3, 2], [5, 1], [5, 2], [5, 2], [4, 2], [4, 3], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [9, 3], [9, 2], [12, 2], [12, 2], [12, 2], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [14, 1], [14, 1], [18, 3], [17, 1], [17, 4]],
    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
      var $0 = $$.length - 1;
      switch (yystate) {
        case 6:
        case 7:
          return yy;
        case 8:
          yy.getLogger().trace("Stop NL ");
          break;
        case 9:
          yy.getLogger().trace("Stop EOF ");
          break;
        case 11:
          yy.getLogger().trace("Stop NL2 ");
          break;
        case 12:
          yy.getLogger().trace("Stop EOF2 ");
          break;
        case 15:
          yy.getLogger().info("Node: ", $$[$0].id);
          yy.addNode($$[$0 - 1].length, $$[$0].id, $$[$0].descr, $$[$0].type);
          break;
        case 16:
          yy.getLogger().trace("Icon: ", $$[$0]);
          yy.decorateNode({ icon: $$[$0] });
          break;
        case 17:
        case 21:
          yy.decorateNode({ class: $$[$0] });
          break;
        case 18:
          yy.getLogger().trace("SPACELIST");
          break;
        case 19:
          yy.getLogger().trace("Node: ", $$[$0].id);
          yy.addNode(0, $$[$0].id, $$[$0].descr, $$[$0].type);
          break;
        case 20:
          yy.decorateNode({ icon: $$[$0] });
          break;
        case 25:
          yy.getLogger().trace("node found ..", $$[$0 - 2]);
          this.$ = { id: $$[$0 - 1], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };
          break;
        case 26:
          this.$ = { id: $$[$0], descr: $$[$0], type: yy.nodeType.DEFAULT };
          break;
        case 27:
          yy.getLogger().trace("node found ..", $$[$0 - 3]);
          this.$ = { id: $$[$0 - 3], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };
          break;
      }
    },
    table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 8: $V0 }, { 1: [3] }, { 1: [2, 1] }, { 4: 6, 6: [1, 7], 7: [1, 8], 8: $V0 }, { 6: $V1, 7: [1, 10], 9: 9, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($V7, [2, 3]), { 1: [2, 2] }, o($V7, [2, 4]), o($V7, [2, 5]), { 1: [2, 6], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V1, 9: 22, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V8, 7: $V9, 10: 23, 11: $Va }, o($Vb, [2, 22], { 17: 17, 18: 18, 14: 27, 15: [1, 28], 16: [1, 29], 19: $V5, 22: $V6 }), o($Vb, [2, 18]), o($Vb, [2, 19]), o($Vb, [2, 20]), o($Vb, [2, 21]), o($Vb, [2, 23]), o($Vb, [2, 24]), o($Vb, [2, 26], { 19: [1, 30] }), { 20: [1, 31] }, { 6: $V8, 7: $V9, 10: 32, 11: $Va }, { 1: [2, 7], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($Vc, [2, 14], { 7: $Vd, 11: $Ve }), o($Vf, [2, 8]), o($Vf, [2, 9]), o($Vf, [2, 10]), o($Vb, [2, 15]), o($Vb, [2, 16]), o($Vb, [2, 17]), { 20: [1, 35] }, { 21: [1, 36] }, o($Vc, [2, 13], { 7: $Vd, 11: $Ve }), o($Vf, [2, 11]), o($Vf, [2, 12]), { 21: [1, 37] }, o($Vb, [2, 25]), o($Vb, [2, 27])],
    defaultActions: { 2: [2, 1], 6: [2, 2] },
    parseError: function parseError2(str, hash) {
      if (hash.recoverable) {
        this.trace(str);
      } else {
        var error = new Error(str);
        error.hash = hash;
        throw error;
      }
    },
    parse: function parse(input) {
      var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1;
      var args = lstack.slice.call(arguments, 1);
      var lexer2 = Object.create(this.lexer);
      var sharedState = { yy: {} };
      for (var k in this.yy) {
        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
          sharedState.yy[k] = this.yy[k];
        }
      }
      lexer2.setInput(input, sharedState.yy);
      sharedState.yy.lexer = lexer2;
      sharedState.yy.parser = this;
      if (typeof lexer2.yylloc == "undefined") {
        lexer2.yylloc = {};
      }
      var yyloc = lexer2.yylloc;
      lstack.push(yyloc);
      var ranges = lexer2.options && lexer2.options.ranges;
      if (typeof sharedState.yy.parseError === "function") {
        this.parseError = sharedState.yy.parseError;
      } else {
        this.parseError = Object.getPrototypeOf(this).parseError;
      }
      function lex() {
        var token;
        token = tstack.pop() || lexer2.lex() || EOF;
        if (typeof token !== "number") {
          if (token instanceof Array) {
            tstack = token;
            token = tstack.pop();
          }
          token = self.symbols_[token] || token;
        }
        return token;
      }
      var symbol, state, action, r, yyval = {}, p, len, newState, expected;
      while (true) {
        state = stack[stack.length - 1];
        if (this.defaultActions[state]) {
          action = this.defaultActions[state];
        } else {
          if (symbol === null || typeof symbol == "undefined") {
            symbol = lex();
          }
          action = table[state] && table[state][symbol];
        }
        if (typeof action === "undefined" || !action.length || !action[0]) {
          var errStr = "";
          expected = [];
          for (p in table[state]) {
            if (this.terminals_[p] && p > TERROR) {
              expected.push("'" + this.terminals_[p] + "'");
            }
          }
          if (lexer2.showPosition) {
            errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
          } else {
            errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
          }
          this.parseError(errStr, {
            text: lexer2.match,
            token: this.terminals_[symbol] || symbol,
            line: lexer2.yylineno,
            loc: yyloc,
            expected
          });
        }
        if (action[0] instanceof Array && action.length > 1) {
          throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
        }
        switch (action[0]) {
          case 1:
            stack.push(symbol);
            vstack.push(lexer2.yytext);
            lstack.push(lexer2.yylloc);
            stack.push(action[1]);
            symbol = null;
            {
              yyleng = lexer2.yyleng;
              yytext = lexer2.yytext;
              yylineno = lexer2.yylineno;
              yyloc = lexer2.yylloc;
            }
            break;
          case 2:
            len = this.productions_[action[1]][1];
            yyval.$ = vstack[vstack.length - len];
            yyval._$ = {
              first_line: lstack[lstack.length - (len || 1)].first_line,
              last_line: lstack[lstack.length - 1].last_line,
              first_column: lstack[lstack.length - (len || 1)].first_column,
              last_column: lstack[lstack.length - 1].last_column
            };
            if (ranges) {
              yyval._$.range = [
                lstack[lstack.length - (len || 1)].range[0],
                lstack[lstack.length - 1].range[1]
              ];
            }
            r = this.performAction.apply(yyval, [
              yytext,
              yyleng,
              yylineno,
              sharedState.yy,
              action[1],
              vstack,
              lstack
            ].concat(args));
            if (typeof r !== "undefined") {
              return r;
            }
            if (len) {
              stack = stack.slice(0, -1 * len * 2);
              vstack = vstack.slice(0, -1 * len);
              lstack = lstack.slice(0, -1 * len);
            }
            stack.push(this.productions_[action[1]][0]);
            vstack.push(yyval.$);
            lstack.push(yyval._$);
            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
            stack.push(newState);
            break;
          case 3:
            return true;
        }
      }
      return true;
    }
  };
  var lexer = function() {
    var lexer2 = {
      EOF: 1,
      parseError: function parseError2(str, hash) {
        if (this.yy.parser) {
          this.yy.parser.parseError(str, hash);
        } else {
          throw new Error(str);
        }
      },
      // resets the lexer, sets new input
      setInput: function(input, yy) {
        this.yy = yy || this.yy || {};
        this._input = input;
        this._more = this._backtrack = this.done = false;
        this.yylineno = this.yyleng = 0;
        this.yytext = this.matched = this.match = "";
        this.conditionStack = ["INITIAL"];
        this.yylloc = {
          first_line: 1,
          first_column: 0,
          last_line: 1,
          last_column: 0
        };
        if (this.options.ranges) {
          this.yylloc.range = [0, 0];
        }
        this.offset = 0;
        return this;
      },
      // consumes and returns one char from the input
      input: function() {
        var ch = this._input[0];
        this.yytext += ch;
        this.yyleng++;
        this.offset++;
        this.match += ch;
        this.matched += ch;
        var lines = ch.match(/(?:\r\n?|\n).*/g);
        if (lines) {
          this.yylineno++;
          this.yylloc.last_line++;
        } else {
          this.yylloc.last_column++;
        }
        if (this.options.ranges) {
          this.yylloc.range[1]++;
        }
        this._input = this._input.slice(1);
        return ch;
      },
      // unshifts one char (or a string) into the input
      unput: function(ch) {
        var len = ch.length;
        var lines = ch.split(/(?:\r\n?|\n)/g);
        this._input = ch + this._input;
        this.yytext = this.yytext.substr(0, this.yytext.length - len);
        this.offset -= len;
        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
        this.match = this.match.substr(0, this.match.length - 1);
        this.matched = this.matched.substr(0, this.matched.length - 1);
        if (lines.length - 1) {
          this.yylineno -= lines.length - 1;
        }
        var r = this.yylloc.range;
        this.yylloc = {
          first_line: this.yylloc.first_line,
          last_line: this.yylineno + 1,
          first_column: this.yylloc.first_column,
          last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
        };
        if (this.options.ranges) {
          this.yylloc.range = [r[0], r[0] + this.yyleng - len];
        }
        this.yyleng = this.yytext.length;
        return this;
      },
      // When called from action, caches matched text and appends it on next action
      more: function() {
        this._more = true;
        return this;
      },
      // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
      reject: function() {
        if (this.options.backtrack_lexer) {
          this._backtrack = true;
        } else {
          return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), {
            text: "",
            token: null,
            line: this.yylineno
          });
        }
        return this;
      },
      // retain first n characters of the match
      less: function(n) {
        this.unput(this.match.slice(n));
      },
      // displays already matched input, i.e. for error messages
      pastInput: function() {
        var past = this.matched.substr(0, this.matched.length - this.match.length);
        return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, "");
      },
      // displays upcoming input, i.e. for error messages
      upcomingInput: function() {
        var next = this.match;
        if (next.length < 20) {
          next += this._input.substr(0, 20 - next.length);
        }
        return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, "");
      },
      // displays the character position where the lexing error occurred, i.e. for error messages
      showPosition: function() {
        var pre = this.pastInput();
        var c = new Array(pre.length + 1).join("-");
        return pre + this.upcomingInput() + "\n" + c + "^";
      },
      // test the lexed token: return FALSE when not a match, otherwise return token
      test_match: function(match, indexed_rule) {
        var token, lines, backup;
        if (this.options.backtrack_lexer) {
          backup = {
            yylineno: this.yylineno,
            yylloc: {
              first_line: this.yylloc.first_line,
              last_line: this.last_line,
              first_column: this.yylloc.first_column,
              last_column: this.yylloc.last_column
            },
            yytext: this.yytext,
            match: this.match,
            matches: this.matches,
            matched: this.matched,
            yyleng: this.yyleng,
            offset: this.offset,
            _more: this._more,
            _input: this._input,
            yy: this.yy,
            conditionStack: this.conditionStack.slice(0),
            done: this.done
          };
          if (this.options.ranges) {
            backup.yylloc.range = this.yylloc.range.slice(0);
          }
        }
        lines = match[0].match(/(?:\r\n?|\n).*/g);
        if (lines) {
          this.yylineno += lines.length;
        }
        this.yylloc = {
          first_line: this.yylloc.last_line,
          last_line: this.yylineno + 1,
          first_column: this.yylloc.last_column,
          last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length
        };
        this.yytext += match[0];
        this.match += match[0];
        this.matches = match;
        this.yyleng = this.yytext.length;
        if (this.options.ranges) {
          this.yylloc.range = [this.offset, this.offset += this.yyleng];
        }
        this._more = false;
        this._backtrack = false;
        this._input = this._input.slice(match[0].length);
        this.matched += match[0];
        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
        if (this.done && this._input) {
          this.done = false;
        }
        if (token) {
          return token;
        } else if (this._backtrack) {
          for (var k in backup) {
            this[k] = backup[k];
          }
          return false;
        }
        return false;
      },
      // return next match in input
      next: function() {
        if (this.done) {
          return this.EOF;
        }
        if (!this._input) {
          this.done = true;
        }
        var token, match, tempMatch, index;
        if (!this._more) {
          this.yytext = "";
          this.match = "";
        }
        var rules = this._currentRules();
        for (var i = 0; i < rules.length; i++) {
          tempMatch = this._input.match(this.rules[rules[i]]);
          if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
            match = tempMatch;
            index = i;
            if (this.options.backtrack_lexer) {
              token = this.test_match(tempMatch, rules[i]);
              if (token !== false) {
                return token;
              } else if (this._backtrack) {
                match = false;
                continue;
              } else {
                return false;
              }
            } else if (!this.options.flex) {
              break;
            }
          }
        }
        if (match) {
          token = this.test_match(match, rules[index]);
          if (token !== false) {
            return token;
          }
          return false;
        }
        if (this._input === "") {
          return this.EOF;
        } else {
          return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), {
            text: "",
            token: null,
            line: this.yylineno
          });
        }
      },
      // return next match that has a token
      lex: function lex() {
        var r = this.next();
        if (r) {
          return r;
        } else {
          return this.lex();
        }
      },
      // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
      begin: function begin(condition) {
        this.conditionStack.push(condition);
      },
      // pop the previously active lexer condition state off the condition stack
      popState: function popState() {
        var n = this.conditionStack.length - 1;
        if (n > 0) {
          return this.conditionStack.pop();
        } else {
          return this.conditionStack[0];
        }
      },
      // produce the lexer rule set which is active for the currently active lexer condition state
      _currentRules: function _currentRules() {
        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
          return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
        } else {
          return this.conditions["INITIAL"].rules;
        }
      },
      // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
      topState: function topState(n) {
        n = this.conditionStack.length - 1 - Math.abs(n || 0);
        if (n >= 0) {
          return this.conditionStack[n];
        } else {
          return "INITIAL";
        }
      },
      // alias for begin(condition)
      pushState: function pushState(condition) {
        this.begin(condition);
      },
      // return the number of states currently on the stack
      stateStackSize: function stateStackSize() {
        return this.conditionStack.length;
      },
      options: { "case-insensitive": true },
      performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
        switch ($avoiding_name_collisions) {
          case 0:
            yy.getLogger().trace("Found comment", yy_.yytext);
            break;
          case 1:
            return 8;
          case 2:
            this.begin("CLASS");
            break;
          case 3:
            this.popState();
            return 16;
          case 4:
            this.popState();
            break;
          case 5:
            yy.getLogger().trace("Begin icon");
            this.begin("ICON");
            break;
          case 6:
            yy.getLogger().trace("SPACELINE");
            return 6;
          case 7:
            return 7;
          case 8:
            return 15;
          case 9:
            yy.getLogger().trace("end icon");
            this.popState();
            break;
          case 10:
            yy.getLogger().trace("Exploding node");
            this.begin("NODE");
            return 19;
          case 11:
            yy.getLogger().trace("Cloud");
            this.begin("NODE");
            return 19;
          case 12:
            yy.getLogger().trace("Explosion Bang");
            this.begin("NODE");
            return 19;
          case 13:
            yy.getLogger().trace("Cloud Bang");
            this.begin("NODE");
            return 19;
          case 14:
            this.begin("NODE");
            return 19;
          case 15:
            this.begin("NODE");
            return 19;
          case 16:
            this.begin("NODE");
            return 19;
          case 17:
            this.begin("NODE");
            return 19;
          case 18:
            return 13;
          case 19:
            return 22;
          case 20:
            return 11;
          case 21:
            yy.getLogger().trace("Starting NSTR");
            this.begin("NSTR");
            break;
          case 22:
            yy.getLogger().trace("description:", yy_.yytext);
            return "NODE_DESCR";
          case 23:
            this.popState();
            break;
          case 24:
            this.popState();
            yy.getLogger().trace("node end ))");
            return "NODE_DEND";
          case 25:
            this.popState();
            yy.getLogger().trace("node end )");
            return "NODE_DEND";
          case 26:
            this.popState();
            yy.getLogger().trace("node end ...", yy_.yytext);
            return "NODE_DEND";
          case 27:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 28:
            this.popState();
            yy.getLogger().trace("node end (-");
            return "NODE_DEND";
          case 29:
            this.popState();
            yy.getLogger().trace("node end (-");
            return "NODE_DEND";
          case 30:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 31:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 32:
            yy.getLogger().trace("Long description:", yy_.yytext);
            return 20;
          case 33:
            yy.getLogger().trace("Long description:", yy_.yytext);
            return 20;
        }
      },
      rules: [/^(?:\s*%%.*)/i, /^(?:mindmap\b)/i, /^(?::::)/i, /^(?:.+)/i, /^(?:\n)/i, /^(?:::icon\()/i, /^(?:[\s]+[\n])/i, /^(?:[\n]+)/i, /^(?:[^\)]+)/i, /^(?:\))/i, /^(?:-\))/i, /^(?:\(-)/i, /^(?:\)\))/i, /^(?:\))/i, /^(?:\(\()/i, /^(?:\{\{)/i, /^(?:\()/i, /^(?:\[)/i, /^(?:[\s]+)/i, /^(?:[^\(\[\n\-\)\{\}]+)/i, /^(?:$)/i, /^(?:["])/i, /^(?:[^"]+)/i, /^(?:["])/i, /^(?:[\)]\))/i, /^(?:[\)])/i, /^(?:[\]])/i, /^(?:\}\})/i, /^(?:\(-)/i, /^(?:-\))/i, /^(?:\(\()/i, /^(?:\()/i, /^(?:[^\)\]\(\}]+)/i, /^(?:.+(?!\(\())/i],
      conditions: { "CLASS": { "rules": [3, 4], "inclusive": false }, "ICON": { "rules": [8, 9], "inclusive": false }, "NSTR": { "rules": [22, 23], "inclusive": false }, "NODE": { "rules": [21, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "inclusive": true } }
    };
    return lexer2;
  }();
  parser2.lexer = lexer;
  function Parser() {
    this.yy = {};
  }
  Parser.prototype = parser2;
  parser2.Parser = Parser;
  return new Parser();
}();
parser.parser = parser;
const mindmapParser = parser;
const sanitizeText = (text) => (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.n)(text, (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)());
let nodes = [];
let cnt = 0;
let elements = {};
const clear = () => {
  nodes = [];
  cnt = 0;
  elements = {};
};
const getParent = function(level) {
  for (let i = nodes.length - 1; i >= 0; i--) {
    if (nodes[i].level < level) {
      return nodes[i];
    }
  }
  return null;
};
const getMindmap = () => {
  return nodes.length > 0 ? nodes[0] : null;
};
const addNode = (level, id, descr, type) => {
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("addNode", level, id, descr, type);
  const conf = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)();
  const node = {
    id: cnt++,
    nodeId: sanitizeText(id),
    level,
    descr: sanitizeText(descr),
    type,
    children: [],
    width: (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)().mindmap.maxNodeWidth
  };
  switch (node.type) {
    case nodeType.ROUNDED_RECT:
      node.padding = 2 * conf.mindmap.padding;
      break;
    case nodeType.RECT:
      node.padding = 2 * conf.mindmap.padding;
      break;
    case nodeType.HEXAGON:
      node.padding = 2 * conf.mindmap.padding;
      break;
    default:
      node.padding = conf.mindmap.padding;
  }
  const parent = getParent(level);
  if (parent) {
    parent.children.push(node);
    nodes.push(node);
  } else {
    if (nodes.length === 0) {
      nodes.push(node);
    } else {
      let error = new Error(
        'There can be only one root. No parent could be found for ("' + node.descr + '")'
      );
      error.hash = {
        text: "branch " + name,
        token: "branch " + name,
        line: "1",
        loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
        expected: ['"checkout ' + name + '"']
      };
      throw error;
    }
  }
};
const nodeType = {
  DEFAULT: 0,
  NO_BORDER: 0,
  ROUNDED_RECT: 1,
  RECT: 2,
  CIRCLE: 3,
  CLOUD: 4,
  BANG: 5,
  HEXAGON: 6
};
const getType = (startStr, endStr) => {
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.debug("In get type", startStr, endStr);
  switch (startStr) {
    case "[":
      return nodeType.RECT;
    case "(":
      return endStr === ")" ? nodeType.ROUNDED_RECT : nodeType.CLOUD;
    case "((":
      return nodeType.CIRCLE;
    case ")":
      return nodeType.CLOUD;
    case "))":
      return nodeType.BANG;
    case "{{":
      return nodeType.HEXAGON;
    default:
      return nodeType.DEFAULT;
  }
};
const setElementForId = (id, element) => {
  elements[id] = element;
};
const decorateNode = (decoration) => {
  const node = nodes[nodes.length - 1];
  if (decoration && decoration.icon) {
    node.icon = sanitizeText(decoration.icon);
  }
  if (decoration && decoration.class) {
    node.class = sanitizeText(decoration.class);
  }
};
const type2Str = (type) => {
  switch (type) {
    case nodeType.DEFAULT:
      return "no-border";
    case nodeType.RECT:
      return "rect";
    case nodeType.ROUNDED_RECT:
      return "rounded-rect";
    case nodeType.CIRCLE:
      return "circle";
    case nodeType.CLOUD:
      return "cloud";
    case nodeType.BANG:
      return "bang";
    case nodeType.HEXAGON:
      return "hexgon";
    default:
      return "no-border";
  }
};
let parseError;
const setErrorHandler = (handler) => {
  parseError = handler;
};
const getLogger = () => _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l;
const getNodeById = (id) => nodes[id];
const getElementById = (id) => elements[id];
const mindmapDb = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  addNode,
  clear,
  decorateNode,
  getElementById,
  getLogger,
  getMindmap,
  getNodeById,
  getType,
  nodeType,
  get parseError() {
    return parseError;
  },
  sanitizeText,
  setElementForId,
  setErrorHandler,
  type2Str
}, Symbol.toStringTag, { value: "Module" }));
const MAX_SECTIONS = 12;
function wrap(text, width) {
  text.each(function() {
    var text2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(this), words = text2.text().split(/(\s+|<br>)/).reverse(), word, line = [], lineHeight = 1.1, y = text2.attr("y"), dy = parseFloat(text2.attr("dy")), tspan = text2.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    for (let j = 0; j < words.length; j++) {
      word = words[words.length - 1 - j];
      line.push(word);
      tspan.text(line.join(" ").trim());
      if (tspan.node().getComputedTextLength() > width || word === "<br>") {
        line.pop();
        tspan.text(line.join(" ").trim());
        if (word === "<br>") {
          line = [""];
        } else {
          line = [word];
        }
        tspan = text2.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word);
      }
    }
  });
}
const defaultBkg = function(elem, node, section) {
  const rd = 5;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z`
  );
  elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height);
};
const rectBkg = function(elem, node) {
  elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("width", node.width);
};
const cloudBkg = function(elem, node) {
  const w = node.width;
  const h = node.height;
  const r1 = 0.15 * w;
  const r2 = 0.25 * w;
  const r3 = 0.35 * w;
  const r4 = 0.2 * w;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 0 a${r1},${r1} 0 0,1 ${w * 0.25},${-1 * w * 0.1}
      a${r3},${r3} 1 0,1 ${w * 0.4},${-1 * w * 0.1}
      a${r2},${r2} 1 0,1 ${w * 0.35},${1 * w * 0.2}

      a${r1},${r1} 1 0,1 ${w * 0.15},${1 * h * 0.35}
      a${r4},${r4} 1 0,1 ${-1 * w * 0.15},${1 * h * 0.65}

      a${r2},${r1} 1 0,1 ${-1 * w * 0.25},${w * 0.15}
      a${r3},${r3} 1 0,1 ${-1 * w * 0.5},${0}
      a${r1},${r1} 1 0,1 ${-1 * w * 0.25},${-1 * w * 0.15}

      a${r1},${r1} 1 0,1 ${-1 * w * 0.1},${-1 * h * 0.35}
      a${r4},${r4} 1 0,1 ${w * 0.1},${-1 * h * 0.65}

    H0 V0 Z`
  );
};
const bangBkg = function(elem, node) {
  const w = node.width;
  const h = node.height;
  const r = 0.15 * w;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 0 a${r},${r} 1 0,0 ${w * 0.25},${-1 * h * 0.1}
      a${r},${r} 1 0,0 ${w * 0.25},${0}
      a${r},${r} 1 0,0 ${w * 0.25},${0}
      a${r},${r} 1 0,0 ${w * 0.25},${1 * h * 0.1}

      a${r},${r} 1 0,0 ${w * 0.15},${1 * h * 0.33}
      a${r * 0.8},${r * 0.8} 1 0,0 ${0},${1 * h * 0.34}
      a${r},${r} 1 0,0 ${-1 * w * 0.15},${1 * h * 0.33}

      a${r},${r} 1 0,0 ${-1 * w * 0.25},${h * 0.15}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${-1 * h * 0.15}

      a${r},${r} 1 0,0 ${-1 * w * 0.1},${-1 * h * 0.33}
      a${r * 0.8},${r * 0.8} 1 0,0 ${0},${-1 * h * 0.34}
      a${r},${r} 1 0,0 ${w * 0.1},${-1 * h * 0.33}

    H0 V0 Z`
  );
};
const circleBkg = function(elem, node) {
  elem.append("circle").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("r", node.width / 2);
};
function insertPolygonShape(parent, w, h, points, node) {
  return parent.insert("polygon", ":first-child").attr(
    "points",
    points.map(function(d) {
      return d.x + "," + d.y;
    }).join(" ")
  ).attr("transform", "translate(" + (node.width - w) / 2 + ", " + h + ")");
}
const hexagonBkg = function(elem, node) {
  const h = node.height;
  const f = 4;
  const m = h / f;
  const w = node.width - node.padding + 2 * m;
  const points = [
    { x: m, y: 0 },
    { x: w - m, y: 0 },
    { x: w, y: -h / 2 },
    { x: w - m, y: -h },
    { x: m, y: -h },
    { x: 0, y: -h / 2 }
  ];
  insertPolygonShape(elem, w, h, points, node);
};
const roundedRectBkg = function(elem, node) {
  elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("rx", node.padding).attr("ry", node.padding).attr("width", node.width);
};
const drawNode = function(elem, node, fullSection, conf) {
  const section = fullSection % (MAX_SECTIONS - 1);
  const nodeElem = elem.append("g");
  node.section = section;
  let sectionClass = "section-" + section;
  if (section < 0) {
    sectionClass += " section-root";
  }
  nodeElem.attr("class", (node.class ? node.class + " " : "") + "mindmap-node " + sectionClass);
  const bkgElem = nodeElem.append("g");
  const textElem = nodeElem.append("g");
  const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width);
  const bbox = txt.node().getBBox();
  const fontSize = conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize;
  node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
  node.width = bbox.width + 2 * node.padding;
  if (node.icon) {
    if (node.type === nodeType.CIRCLE) {
      node.height += 50;
      node.width += 50;
      const icon = nodeElem.append("foreignObject").attr("height", "50px").attr("width", node.width).attr("style", "text-align: center;");
      icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon);
      textElem.attr(
        "transform",
        "translate(" + node.width / 2 + ", " + (node.height / 2 - 1.5 * node.padding) + ")"
      );
    } else {
      node.width += 50;
      const orgHeight = node.height;
      node.height = Math.max(orgHeight, 60);
      const heightDiff = Math.abs(node.height - orgHeight);
      const icon = nodeElem.append("foreignObject").attr("width", "60px").attr("height", node.height).attr("style", "text-align: center;margin-top:" + heightDiff / 2 + "px;");
      icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon);
      textElem.attr(
        "transform",
        "translate(" + (25 + node.width / 2) + ", " + (heightDiff / 2 + node.padding / 2) + ")"
      );
    }
  } else {
    textElem.attr("transform", "translate(" + node.width / 2 + ", " + node.padding / 2 + ")");
  }
  switch (node.type) {
    case nodeType.DEFAULT:
      defaultBkg(bkgElem, node, section);
      break;
    case nodeType.ROUNDED_RECT:
      roundedRectBkg(bkgElem, node);
      break;
    case nodeType.RECT:
      rectBkg(bkgElem, node);
      break;
    case nodeType.CIRCLE:
      bkgElem.attr("transform", "translate(" + node.width / 2 + ", " + +node.height / 2 + ")");
      circleBkg(bkgElem, node);
      break;
    case nodeType.CLOUD:
      cloudBkg(bkgElem, node);
      break;
    case nodeType.BANG:
      bangBkg(bkgElem, node);
      break;
    case nodeType.HEXAGON:
      hexagonBkg(bkgElem, node);
      break;
  }
  setElementForId(node.id, nodeElem);
  return node.height;
};
const drawEdge = function drawEdge2(edgesElem, mindmap, parent, depth, fullSection) {
  const section = fullSection % (MAX_SECTIONS - 1);
  const sx = parent.x + parent.width / 2;
  const sy = parent.y + parent.height / 2;
  const ex = mindmap.x + mindmap.width / 2;
  const ey = mindmap.y + mindmap.height / 2;
  const mx = ex > sx ? sx + Math.abs(sx - ex) / 2 : sx - Math.abs(sx - ex) / 2;
  const my = ey > sy ? sy + Math.abs(sy - ey) / 2 : sy - Math.abs(sy - ey) / 2;
  const qx = ex > sx ? Math.abs(sx - mx) / 2 + sx : -Math.abs(sx - mx) / 2 + sx;
  const qy = ey > sy ? Math.abs(sy - my) / 2 + sy : -Math.abs(sy - my) / 2 + sy;
  edgesElem.append("path").attr(
    "d",
    parent.direction === "TB" || parent.direction === "BT" ? `M${sx},${sy} Q${sx},${qy} ${mx},${my} T${ex},${ey}` : `M${sx},${sy} Q${qx},${sy} ${mx},${my} T${ex},${ey}`
  ).attr("class", "edge section-edge-" + section + " edge-depth-" + depth);
};
const positionNode = function(node) {
  const nodeElem = getElementById(node.id);
  const x = node.x || 0;
  const y = node.y || 0;
  nodeElem.attr("transform", "translate(" + x + "," + y + ")");
};
const svgDraw = { drawNode, positionNode, drawEdge };
cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default().use((cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default()));
function drawNodes(svg, mindmap, section, conf) {
  svgDraw.drawNode(svg, mindmap, section, conf);
  if (mindmap.children) {
    mindmap.children.forEach((child, index) => {
      drawNodes(svg, child, section < 0 ? index : section, conf);
    });
  }
}
function drawEdges(edgesEl, cy) {
  cy.edges().map((edge, id) => {
    const data = edge.data();
    if (edge[0]._private.bodyBounds) {
      const bounds = edge[0]._private.rscratch;
      _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.trace("Edge: ", id, data);
      edgesEl.insert("path").attr(
        "d",
        `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} `
      ).attr("class", "edge section-edge-" + data.section + " edge-depth-" + data.depth);
    }
  });
}
function addNodes(mindmap, cy, conf, level) {
  cy.add({
    group: "nodes",
    data: {
      id: mindmap.id,
      labelText: mindmap.descr,
      height: mindmap.height,
      width: mindmap.width,
      level,
      nodeId: mindmap.id,
      padding: mindmap.padding,
      type: mindmap.type
    },
    position: {
      x: mindmap.x,
      y: mindmap.y
    }
  });
  if (mindmap.children) {
    mindmap.children.forEach((child) => {
      addNodes(child, cy, conf, level + 1);
      cy.add({
        group: "edges",
        data: {
          id: `${mindmap.id}_${child.id}`,
          source: mindmap.id,
          target: child.id,
          depth: level,
          section: child.section
        }
      });
    });
  }
}
function layoutMindmap(node, conf) {
  return new Promise((resolve) => {
    const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body").append("div").attr("id", "cy").attr("style", "display:none");
    const cy = cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default()({
      container: document.getElementById("cy"),
      // container to render in
      style: [
        {
          selector: "edge",
          style: {
            "curve-style": "bezier"
          }
        }
      ]
    });
    renderEl.remove();
    addNodes(node, cy, conf, 0);
    cy.nodes().forEach(function(n) {
      n.layoutDimensions = () => {
        const data = n.data();
        return { w: data.width, h: data.height };
      };
    });
    cy.layout({
      name: "cose-bilkent",
      quality: "proof",
      // headless: true,
      styleEnabled: false,
      animate: false
    }).run();
    cy.ready((e) => {
      _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("Ready", e);
      resolve(cy);
    });
  });
}
function positionNodes(cy) {
  cy.nodes().map((node, id) => {
    const data = node.data();
    data.x = node.position().x;
    data.y = node.position().y;
    svgDraw.positionNode(data);
    const el = getElementById(data.nodeId);
    _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("Id:", id, "Position: (", node.position().x, ", ", node.position().y, ")", data);
    el.attr(
      "transform",
      `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})`
    );
    el.attr("attr", `apa-${id})`);
  });
}
const draw = async (text, id, version, diagObj) => {
  const conf = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)();
  diagObj.db.clear();
  diagObj.parser.parse(text);
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.debug("Renering info diagram\n" + text);
  const securityLevel = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)().securityLevel;
  let sandboxElement;
  if (securityLevel === "sandbox") {
    sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("#i" + id);
  }
  const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ys)("body");
  const svg = root.select("#" + id);
  svg.append("g");
  const mm = diagObj.db.getMindmap();
  const edgesElem = svg.append("g");
  edgesElem.attr("class", "mindmap-edges");
  const nodesElem = svg.append("g");
  nodesElem.attr("class", "mindmap-nodes");
  drawNodes(nodesElem, mm, -1, conf);
  const cy = await layoutMindmap(mm, conf);
  drawEdges(edgesElem, cy);
  positionNodes(cy);
  (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.s)(void 0, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
};
const mindmapRenderer = {
  draw
};
const genSections = (options) => {
  let sections = "";
  for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
    options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i];
    if ((0,khroma__WEBPACK_IMPORTED_MODULE_14__/* ["default"] */ .Z)(options["lineColor" + i])) {
      options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_15__/* ["default"] */ .Z)(options["lineColor" + i], 20);
    } else {
      options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_16__/* ["default"] */ .Z)(options["lineColor" + i], 20);
    }
  }
  for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
    const sw = "" + (17 - 3 * i);
    sections += `
    .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} polygon, .section-${i - 1} path  {
      fill: ${options["cScale" + i]};
    }
    .section-${i - 1} text {
     fill: ${options["cScaleLabel" + i]};
    }
    .node-icon-${i - 1} {
      font-size: 40px;
      color: ${options["cScaleLabel" + i]};
    }
    .section-edge-${i - 1}{
      stroke: ${options["cScale" + i]};
    }
    .edge-depth-${i - 1}{
      stroke-width: ${sw};
    }
    .section-${i - 1} line {
      stroke: ${options["cScaleInv" + i]} ;
      stroke-width: 3;
    }

    .disabled, .disabled circle, .disabled text {
      fill: lightgray;
    }
    .disabled text {
      fill: #efefef;
    }
    `;
  }
  return sections;
};
const getStyles = (options) => `
  .edge {
    stroke-width: 3;
  }
  ${genSections(options)}
  .section-root rect, .section-root path, .section-root circle, .section-root polygon  {
    fill: ${options.git0};
  }
  .section-root text {
    fill: ${options.gitBranchLabel0};
  }
  .icon-container {
    height:100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .edge {
    fill: none;
  }
`;
const mindmapStyles = getStyles;
const diagram = {
  db: mindmapDb,
  renderer: mindmapRenderer,
  parser: mindmapParser,
  styles: mindmapStyles
};

//# sourceMappingURL=mindmap-definition-44684416.js.map


/***/ }),

/***/ 91619:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  Z: () => (/* binding */ is_dark)
});

// EXTERNAL MODULE: ./node_modules/khroma/dist/utils/index.js + 3 modules
var utils = __webpack_require__(61691);
// EXTERNAL MODULE: ./node_modules/khroma/dist/color/index.js + 4 modules
var dist_color = __webpack_require__(71610);
;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/luminance.js
/* IMPORT */


/* MAIN */
//SOURCE: https://planetcalc.com/7779
const luminance = (color) => {
    const { r, g, b } = dist_color/* default */.Z.parse(color);
    const luminance = .2126 * utils/* default */.Z.channel.toLinear(r) + .7152 * utils/* default */.Z.channel.toLinear(g) + .0722 * utils/* default */.Z.channel.toLinear(b);
    return utils/* default */.Z.lang.round(luminance);
};
/* EXPORT */
/* harmony default export */ const methods_luminance = (luminance);

;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/is_light.js
/* IMPORT */

/* MAIN */
const isLight = (color) => {
    return methods_luminance(color) >= .5;
};
/* EXPORT */
/* harmony default export */ const is_light = (isLight);

;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/is_dark.js
/* IMPORT */

/* MAIN */
const isDark = (color) => {
    return !is_light(color);
};
/* EXPORT */
/* harmony default export */ const is_dark = (isDark);


/***/ })

};
;