diff --git a/openo-portal/portal-lifecyclemgr/js/topo/Edge.js b/openo-portal/portal-lifecyclemgr/js/topo/Edge.js
new file mode 100644
index 0000000..1083d8e
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/Edge.js
@@ -0,0 +1,18 @@
+var edgeColors = {
+	red : "#f00",
+	green: "#0f0",
+  blue: "#00f",
+  yellow: "#ff0",
+  grey: "#ddd",
+  black: "#000"
+}
+
+function Edge(id, label, source, target, size, color) {
+	this.id = id;
+	this.label = label;
+	this.source = source;
+	this.target = target;
+	this.type = 'line';
+  this.size = size;
+	this.color = edgeColors[color];
+}
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/Node.js b/openo-portal/portal-lifecyclemgr/js/topo/Node.js
new file mode 100644
index 0000000..bae5fc8
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/Node.js
@@ -0,0 +1,20 @@
+var icon = {
+	type1 : "js/topo/img/NEUP.png",
+	type2 : "js/topo/img/NETWORK.png",
+	type3 : "js/topo/img/site.png"
+}
+function Node(id, label, size, type, x, y) {
+	this.id = id;
+	this.label = label;
+	this.type = "square";
+	this.x = x;
+	this.y = y;
+	this.size = size;
+	this.color = "white";
+	this.borderColor = "white";
+	this.image = {
+		url : icon[type],
+		scale : 1.0,
+		clip : 1.0
+	};
+}
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/Topology.js b/openo-portal/portal-lifecyclemgr/js/topo/Topology.js
new file mode 100644
index 0000000..a73fdb1
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/Topology.js
@@ -0,0 +1,98 @@
+function Topology(containerId) {
+
+	/**
+	 * IMPORTANT: This only works with the canvas renderer. TBD in the future
+	 * will also support the WebGL renderer.
+	 */
+	sigma.utils.pkg('sigma.canvas.nodes');
+
+	this.s = new sigma({
+		graph : {
+			nodes : [],
+			edges : []
+		},
+		renderer : {
+			// IMPORTANT:
+			// This works only with the canvas renderer, so the
+			// renderer type set as "canvas" is necessary here.
+			container : document.getElementById(containerId),
+			type : 'canvas'
+		},
+		settings : {
+			minNodeSize : 4,
+			maxNodeSize : 48,
+			edgeLabelSize : 'proportional'
+		}
+	});
+	this.addNode = addNode;
+	this.addEdge = addEdge;
+}
+
+function addNode(node) {
+
+	this.s.graph.addNode(node);
+
+}
+
+function addEdge(edge) {
+	this.s.graph.addEdge(edge);
+}
+
+function init() {
+
+	var node1 = new Node("1", "ThinCPE", 8, "type1", 0.2, 0.5);
+  var node2 = new Node("2", "vCPE", 8, "type1", 0.5, 0.5);
+	var node3 = new Node("3", "VPC", 16, "type2", 0.8, 0.5);
+  
+  var node4 = new Node("4", "Site", 16, "type3", 0.2, 0.55);
+  var node5 = new Node("5", "POP", 24, "type3", 0.5, 0.55);
+	var node6 = new Node("6", "DC", 32, "type3", 0.8, 0.55);
+  
+  var node7 = new Node("7", "vFW", 6, "type1", 0.45, 0.45);
+  var node8 = new Node("8", "vLB", 6, "type1", 0.55, 0.45);
+
+	var edge1 = new Edge("e1", "VxLAN", "1", "2", 0.5, "blue");
+	var edge2 = new Edge("e2", "IPSec", "2", "3", 0.5, "green");
+  
+	var edge3 = new Edge("e3", "in", "1", "4", 0.5, "grey");
+  var edge4 = new Edge("e4", "in", "2", "5", 0.5, "grey");
+  var edge5 = new Edge("e5", "in", "3", "6", 0.5, "grey");
+  
+  var edge6 = new Edge("e6", "L2VPN", "4", "5", 0.5, "black");
+  var edge7 = new Edge("e7", "L3VPN", "5", "6", 0.5, "black");
+  
+  var edge8 = new Edge("e8", "", "2", "7", 0.5, "yellow");
+  var edge9 = new Edge("e9", "", "7", "8", 0.5, "yellow");
+  var edge10 = new Edge("e10", "", "8", "2", 0.5, "yellow");
+  
+	var topology = new Topology("container");
+  
+	topology.addNode(node1);
+	topology.addNode(node2);
+	topology.addNode(node3);
+  topology.addNode(node4);
+	topology.addNode(node5);
+	topology.addNode(node6);
+  topology.addNode(node7);
+	topology.addNode(node8);
+
+	topology.addEdge(edge1);
+	topology.addEdge(edge2);
+  topology.addEdge(edge3);
+  topology.addEdge(edge4);
+	topology.addEdge(edge5);
+  
+  
+  topology.addEdge(edge6);
+	topology.addEdge(edge7);
+  topology.addEdge(edge8);
+	topology.addEdge(edge9);
+  topology.addEdge(edge10);
+  
+	CustomShapes.init(topology.s);
+	topology.s.refresh();
+}
+
+$(document).ready(function() {
+	init();
+});
\ No newline at end of file
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN.png
new file mode 100644
index 0000000..a9bbe5e
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN_selected.png
new file mode 100644
index 0000000..9fc5aaa
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NEDOWN_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK.png
new file mode 100644
index 0000000..931dbe7
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_EDGE.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_EDGE.png
new file mode 100644
index 0000000..779bdd4
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_EDGE.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_selected.png
new file mode 100644
index 0000000..931dbe7
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NETWORK_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP.png
new file mode 100644
index 0000000..b82ea85
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP_selected.png
new file mode 100644
index 0000000..65f0dc8
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/NEUP_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER.png
new file mode 100644
index 0000000..b82ea85
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0.png
new file mode 100644
index 0000000..2099f02
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0_selected.png
new file mode 100644
index 0000000..5a0cf73
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_0_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1.png
new file mode 100644
index 0000000..1e958ad
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1_selected.png
new file mode 100644
index 0000000..429a0be
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_1_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2.png
new file mode 100644
index 0000000..c947de2
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2_selected.png
new file mode 100644
index 0000000..bff92e0
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_2_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3.png
new file mode 100644
index 0000000..1a3f560
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3_selected.png
new file mode 100644
index 0000000..e00bf6d
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_3_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_selected.png
new file mode 100644
index 0000000..65f0dc8
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/OTHER_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/cloud.png b/openo-portal/portal-lifecyclemgr/js/topo/img/cloud.png
new file mode 100644
index 0000000..e14d031
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/cloud.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/cloudroute.png b/openo-portal/portal-lifecyclemgr/js/topo/img/cloudroute.png
new file mode 100644
index 0000000..22d5542
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/cloudroute.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/crossSubnet.png b/openo-portal/portal-lifecyclemgr/js/topo/img/crossSubnet.png
new file mode 100644
index 0000000..71216ac
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/crossSubnet.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/delete_asbr.png b/openo-portal/portal-lifecyclemgr/js/topo/img/delete_asbr.png
new file mode 100644
index 0000000..f9a06bd
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/delete_asbr.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/mark_sink.png b/openo-portal/portal-lifecyclemgr/js/topo/img/mark_sink.png
new file mode 100644
index 0000000..2929f63
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/mark_sink.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/mark_source.png b/openo-portal/portal-lifecyclemgr/js/topo/img/mark_source.png
new file mode 100644
index 0000000..30aa5bb
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/mark_source.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/networkdown.png b/openo-portal/portal-lifecyclemgr/js/topo/img/networkdown.png
new file mode 100644
index 0000000..98c6436
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/networkdown.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/node_gray.png b/openo-portal/portal-lifecyclemgr/js/topo/img/node_gray.png
new file mode 100644
index 0000000..14c287d
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/node_gray.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/node_green.png b/openo-portal/portal-lifecyclemgr/js/topo/img/node_green.png
new file mode 100644
index 0000000..70e91f5
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/node_green.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/node_red.png b/openo-portal/portal-lifecyclemgr/js/topo/img/node_red.png
new file mode 100644
index 0000000..195df92
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/node_red.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/router.png b/openo-portal/portal-lifecyclemgr/js/topo/img/router.png
new file mode 100644
index 0000000..b82ea85
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/router.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/router_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/router_selected.png
new file mode 100644
index 0000000..65f0dc8
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/router_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/site.png b/openo-portal/portal-lifecyclemgr/js/topo/img/site.png
new file mode 100644
index 0000000..b353852
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/site.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/siteIcon_feature.png b/openo-portal/portal-lifecyclemgr/js/topo/img/siteIcon_feature.png
new file mode 100644
index 0000000..9ddf0a3
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/siteIcon_feature.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/site_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/site_selected.png
new file mode 100644
index 0000000..b5c00ae
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/site_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown.png b/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown.png
new file mode 100644
index 0000000..2db4850
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown_selected.png b/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown_selected.png
new file mode 100644
index 0000000..2d5af83
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/sitedown_selected.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/img/u1963.png b/openo-portal/portal-lifecyclemgr/js/topo/img/u1963.png
new file mode 100644
index 0000000..631c9ac
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/img/u1963.png
Binary files differ
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/LICENSE.txt b/openo-portal/portal-lifecyclemgr/js/topo/sigma/LICENSE.txt
new file mode 100644
index 0000000..81739df
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/LICENSE.txt
@@ -0,0 +1,12 @@
+Copyright (C) 2013-2014, Alexis Jacomy, http://sigmajs.org
+
+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.
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/jquery-3.1.0.min.js b/openo-portal/portal-lifecyclemgr/js/topo/sigma/jquery-3.1.0.min.js
new file mode 100644
index 0000000..f6a6a99
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/jquery-3.1.0.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.0",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null!=a?a<0?this[a+this.length]:this[a]:f.call(this)},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c<b?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:h,sort:c.sort,splice:c.splice},r.extend=r.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||r.isFunction(g)||(g={}),h===i&&(g=this,h--);h<i;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(r.isPlainObject(d)||(e=r.isArray(d)))?(e?(e=!1,f=c&&r.isArray(c)?c:[]):f=c&&r.isPlainObject(c)?c:{},g[b]=r.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},r.extend({expando:"jQuery"+(q+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===r.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=r.type(a);return("number"===b||"string"===b)&&!isNaN(a-parseFloat(a))},isPlainObject:function(a){var b,c;return!(!a||"[object Object]"!==k.call(a))&&(!(b=e(a))||(c=l.call(b,"constructor")&&b.constructor,"function"==typeof c&&m.call(c)===n))},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?j[k.call(a)]||"object":typeof a},globalEval:function(a){p(a)},camelCase:function(a){return a.replace(t,"ms-").replace(u,v)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(w(a)){for(c=a.length;d<c;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(s,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(w(Object(a))?r.merge(c,"string"==typeof a?[a]:a):h.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:i.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;d<c;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;f<g;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,f=0,h=[];if(w(a))for(d=a.length;f<d;f++)e=b(a[f],f,c),null!=e&&h.push(e);else for(f in a)e=b(a[f],f,c),null!=e&&h.push(e);return g.apply([],h)},guid:1,proxy:function(a,b){var c,d,e;if("string"==typeof b&&(c=a[b],b=a,a=c),r.isFunction(a))return d=f.call(arguments,2),e=function(){return a.apply(b||this,d.concat(f.call(arguments)))},e.guid=a.guid=a.guid||r.guid++,e},now:Date.now,support:o}),"function"==typeof Symbol&&(r.fn[Symbol.iterator]=c[Symbol.iterator]),r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){j["[object "+b+"]"]=b.toLowerCase()});function w(a){var b=!!a&&"length"in a&&a.length,c=r.type(a);return"function"!==c&&!r.isWindow(a)&&("array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\0-\\xa0])+",M="\\["+K+"*("+L+")(?:"+K+"*([*^$|!~]?=)"+K+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+L+"))|)"+K+"*\\]",N=":("+L+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+M+")*)|.*)\\)|)",O=new RegExp(K+"+","g"),P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"label"in b&&b.disabled===a||"form"in b&&b.disabled===a||"form"in b&&b.disabled===!1&&(b.isDisabled===a||b.isDisabled!==!a&&("label"in b||!ea(b))!==a)}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c<b;c+=2)a.push(c);return a}),odd:pa(function(a,b){for(var c=1;c<b;c+=2)a.push(c);return a}),lt:pa(function(a,b,c){for(var d=c<0?c+b:c;--d>=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function ra(){}ra.prototype=d.filters=d.pseudos,d.setFilters=new ra,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=Q.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=R.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(P," ")}),h=h.slice(c.length));for(g in d.filter)!(e=V[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function sa(a){for(var b=0,c=a.length,d="";b<c;b++)d+=a[b].value;return d}function ta(a,b,c){var d=b.dir,e=b.next,f=e||d,g=c&&"parentNode"===f,h=x++;return b.first?function(b,c,e){while(b=b[d])if(1===b.nodeType||g)return a(b,c,e)}:function(b,c,i){var j,k,l,m=[w,h];if(i){while(b=b[d])if((1===b.nodeType||g)&&a(b,c,i))return!0}else while(b=b[d])if(1===b.nodeType||g)if(l=b[u]||(b[u]={}),k=l[b.uniqueID]||(l[b.uniqueID]={}),e&&e===b.nodeName.toLowerCase())b=b[d]||b;else{if((j=k[f])&&j[0]===w&&j[1]===h)return m[2]=j[2];if(k[f]=m,m[2]=a(b,c,i))return!0}}}function ua(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d<e;d++)ga(a,b[d],c);return c}function wa(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;h<i;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function xa(a,b,c,d,e,f){return d&&!d[u]&&(d=xa(d)),e&&!e[u]&&(e=xa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||va(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:wa(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=wa(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?I(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i<f;i++)if(c=d.relative[a[i].type])m=[ta(ua(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;e<f;e++)if(d.relative[a[e].type])break;return xa(i>1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i<e&&ya(a.slice(i,e)),e<f&&ya(a=a.slice(e)),e<f&&sa(a))}m.push(c)}return ua(m)}function za(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(_,aa),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=V.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(_,aa),$.test(j[0].type)&&qa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&sa(j),!a)return G.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||$.test(a)&&qa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){if(r.isFunction(b))return r.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return r.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(C.test(b))return r.filter(b,a,c);b=r.filter(b,a)}return r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType})}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b<d;b++)if(r.contains(e[b],this))return!0}));for(c=this.pushStack([]),b=0;b<d;b++)r.find(a,e[b],c);return d>1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a<c;a++)if(r.contains(this,b[a]))return!0})},closest:function(a,b){var c,d=0,e=this.length,f=[],g="string"!=typeof a&&r(a);if(!A.test(a))for(;d<e;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/\S+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){r.each(b,function(b,c){r.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==r.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return r.each(arguments,function(a,b){var c;while((c=r.inArray(b,f,c))>-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b<f)){if(a=d.apply(h,i),a===c.promise())throw new TypeError("Thenable self-resolution");j=a&&("object"==typeof a||"function"==typeof a)&&a.then,r.isFunction(j)?e?j.call(a,g(f,c,M,e),g(f,c,N,e)):(f++,j.call(a,g(f,c,M,e),g(f,c,N,e),g(f,c,M,c.notifyWith))):(d!==M&&(h=void 0,i=[a]),(e||c.resolveWith)(h,i))}},k=e?j:function(){try{j()}catch(a){r.Deferred.exceptionHook&&r.Deferred.exceptionHook(a,k.stackTrace),b+1>=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R),a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,
+r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h<i;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},T=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function U(){this.expando=r.expando+U.uid++}U.uid=1,U.prototype={cache:function(a){var b=a[this.expando];return b||(b={},T(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[r.camelCase(b)]=c;else for(d in b)e[r.camelCase(d)]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][r.camelCase(b)]},access:function(a,b,c){return void 0===b||b&&"string"==typeof b&&void 0===c?this.get(a,b):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d=a[this.expando];if(void 0!==d){if(void 0!==b){r.isArray(b)?b=b.map(r.camelCase):(b=r.camelCase(b),b=b in d?[b]:b.match(K)||[]),c=b.length;while(c--)delete d[b[c]]}(void 0===b||r.isEmptyObject(d))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!r.isEmptyObject(b)}};var V=new U,W=new U,X=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Y=/[A-Z]/g;function Z(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Y,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c||"false"!==c&&("null"===c?null:+c+""===c?+c:X.test(c)?JSON.parse(c):c)}catch(e){}W.set(a,b,c)}else c=void 0;return c}r.extend({hasData:function(a){return W.hasData(a)||V.hasData(a)},data:function(a,b,c){return W.access(a,b,c)},removeData:function(a,b){W.remove(a,b)},_data:function(a,b,c){return V.access(a,b,c)},_removeData:function(a,b){V.remove(a,b)}}),r.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=W.get(f),1===f.nodeType&&!V.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=r.camelCase(d.slice(5)),Z(f,d,e[d])));V.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){W.set(this,a)}):S(this,function(b){var c;if(f&&void 0===b){if(c=W.get(f,a),void 0!==c)return c;if(c=Z(f,a),void 0!==c)return c}else this.each(function(){W.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?r.queue(this[0],a):void 0===b?this:this.each(function(){var c=r.queue(this,a,b);r._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&r.dequeue(this,a)})},dequeue:function(a){return this.each(function(){r.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=r.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=V.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var $=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,_=new RegExp("^(?:([+-])=|)("+$+")([a-z%]*)$","i"),aa=["Top","Right","Bottom","Left"],ba=function(a,b){return a=b||a,"none"===a.style.display||""===a.style.display&&r.contains(a.ownerDocument,a)&&"none"===r.css(a,"display")},ca=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};function da(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return r.css(a,b,"")},i=h(),j=c&&c[3]||(r.cssNumber[b]?"":"px"),k=(r.cssNumber[b]||"px"!==j&&+i)&&_.exec(r.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,r.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var ea={};function fa(a){var b,c=a.ownerDocument,d=a.nodeName,e=ea[d];return e?e:(b=c.body.appendChild(c.createElement(d)),e=r.css(b,"display"),b.parentNode.removeChild(b),"none"===e&&(e="block"),ea[d]=e,e)}function ga(a,b){for(var c,d,e=[],f=0,g=a.length;f<g;f++)d=a[f],d.style&&(c=d.style.display,b?("none"===c&&(e[f]=V.get(d,"display")||null,e[f]||(d.style.display="")),""===d.style.display&&ba(d)&&(e[f]=fa(d))):"none"!==c&&(e[f]="none",V.set(d,"display",c)));for(f=0;f<g;f++)null!=e[f]&&(a[f].style.display=e[f]);return a}r.fn.extend({show:function(){return ga(this,!0)},hide:function(){return ga(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){ba(this)?r(this).show():r(this).hide()})}});var ha=/^(?:checkbox|radio)$/i,ia=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,ja=/^$|\/(?:java|ecma)script/i,ka={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ka.optgroup=ka.option,ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead,ka.th=ka.td;function la(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function ma(a,b){for(var c=0,d=a.length;c<d;c++)V.set(a[c],"globalEval",!b||V.get(b[c],"globalEval"))}var na=/<|&#?\w+;/;function oa(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],n=0,o=a.length;n<o;n++)if(f=a[n],f||0===f)if("object"===r.type(f))r.merge(m,f.nodeType?[f]:f);else if(na.test(f)){g=g||l.appendChild(b.createElement("div")),h=(ia.exec(f)||["",""])[1].toLowerCase(),i=ka[h]||ka._default,g.innerHTML=i[1]+r.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;r.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",n=0;while(f=m[n++])if(d&&r.inArray(f,d)>-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=la(l.appendChild(f),"script"),j&&ma(g),c){k=0;while(f=g[k++])ja.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var pa=d.documentElement,qa=/^key/,ra=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,sa=/^([^.]*)(?:\.(.+)|)/;function ta(){return!0}function ua(){return!1}function va(){try{return d.activeElement}catch(a){}}function wa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)wa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ua;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(pa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=sa.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c<arguments.length;c++)i[c]=arguments[c];if(b.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,b)!==!1){h=r.event.handlers.call(this,b,j),c=0;while((f=h[c++])&&!b.isPropagationStopped()){b.currentTarget=f.elem,d=0;while((g=f.handlers[d++])&&!b.isImmediatePropagationStopped())b.rnamespace&&!b.rnamespace.test(g.namespace)||(b.handleObj=g,b.data=g.data,e=((r.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(b.result=e)===!1&&(b.preventDefault(),b.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,b),b.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;c<h;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?r(e,this).index(i)>-1:r.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},addProp:function(a,b){Object.defineProperty(r.Event.prototype,a,{enumerable:!0,configurable:!0,get:r.isFunction(b)?function(){if(this.originalEvent)return b(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[a]},set:function(b){Object.defineProperty(this,a,{enumerable:!0,configurable:!0,writable:!0,value:b})}})},fix:function(a){return a[r.expando]?a:new r.Event(a)},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==va()&&this.focus)return this.focus(),!1},delegateType:"focusin"},blur:{trigger:function(){if(this===va()&&this.blur)return this.blur(),!1},delegateType:"focusout"},click:{trigger:function(){if("checkbox"===this.type&&this.click&&r.nodeName(this,"input"))return this.click(),!1},_default:function(a){return r.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},r.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},r.Event=function(a,b){return this instanceof r.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ta:ua,this.target=a.target&&3===a.target.nodeType?a.target.parentNode:a.target,this.currentTarget=a.currentTarget,this.relatedTarget=a.relatedTarget):this.type=a,b&&r.extend(this,b),this.timeStamp=a&&a.timeStamp||r.now(),void(this[r.expando]=!0)):new r.Event(a,b)},r.Event.prototype={constructor:r.Event,isDefaultPrevented:ua,isPropagationStopped:ua,isImmediatePropagationStopped:ua,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ta,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ta,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ta,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},r.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(a){var b=a.button;return null==a.which&&qa.test(a.type)?null!=a.charCode?a.charCode:a.keyCode:!a.which&&void 0!==b&&ra.test(a.type)?1&b?1:2&b?3:4&b?2:0:a.which}},r.event.addProp),r.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){r.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||r.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),r.fn.extend({on:function(a,b,c,d){return wa(this,a,b,c,d)},one:function(a,b,c,d){return wa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,r(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ua),this.each(function(){r.event.remove(this,a,c,b)})}});var xa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,ya=/<script|<style|<link/i,za=/checked\s*(?:[^=]|=\s*.checked.)/i,Aa=/^true\/(.*)/,Ba=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function Ca(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Da(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ea(a){var b=Aa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c<d;c++)r.event.add(b,e,j[e][c])}W.hasData(a)&&(h=W.access(a),i=r.extend({},h),W.set(b,i))}}function Ga(a,b){var c=b.nodeName.toLowerCase();"input"===c&&ha.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function Ha(a,b,c,d){b=g.apply([],b);var e,f,h,i,j,k,l=0,m=a.length,n=m-1,q=b[0],s=r.isFunction(q);if(s||m>1&&"string"==typeof q&&!o.checkClone&&za.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(m&&(e=oa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(la(e,"script"),Da),i=h.length;l<m;l++)j=e,l!==n&&(j=r.clone(j,!0,!0),i&&r.merge(h,la(j,"script"))),c.call(a[l],j,l);if(i)for(k=h[h.length-1].ownerDocument,r.map(h,Ea),l=0;l<i;l++)j=h[l],ja.test(j.type||"")&&!V.access(j,"globalEval")&&r.contains(k,j)&&(j.src?r._evalUrl&&r._evalUrl(j.src):p(j.textContent.replace(Ba,""),k))}return a}function Ia(a,b,c){for(var d,e=b?r.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||r.cleanData(la(d)),d.parentNode&&(c&&r.contains(d.ownerDocument,d)&&ma(la(d,"script")),d.parentNode.removeChild(d));return a}r.extend({htmlPrefilter:function(a){return a.replace(xa,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=la(h),f=la(a),d=0,e=f.length;d<e;d++)Ga(f[d],g[d]);if(b)if(c)for(f=f||la(a),g=g||la(h),d=0,e=f.length;d<e;d++)Fa(f[d],g[d]);else Fa(a,h);return g=la(h,"script"),g.length>0&&ma(g,!i&&la(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(la(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!ya.test(a)&&!ka[(ia.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c<d;c++)b=this[c]||{},1===b.nodeType&&(r.cleanData(la(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;r.inArray(this,a)<0&&(r.cleanData(la(this)),c&&c.replaceChild(b,this))},a)}}),r.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){r.fn[a]=function(a){for(var c,d=[],e=r(a),f=e.length-1,g=0;g<=f;g++)c=g===f?this:this.clone(!0),r(e[g])[b](c),h.apply(d,c.get());return this.pushStack(d)}});var Ja=/^margin/,Ka=new RegExp("^("+$+")(?!px)[a-z%]+$","i"),La=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)};!function(){function b(){if(i){i.style.cssText="box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",i.innerHTML="",pa.appendChild(h);var b=a.getComputedStyle(i);c="1%"!==b.top,g="2px"===b.marginLeft,e="4px"===b.width,i.style.marginRight="50%",f="4px"===b.marginRight,pa.removeChild(h),i=null}}var c,e,f,g,h=d.createElement("div"),i=d.createElement("div");i.style&&(i.style.backgroundClip="content-box",i.cloneNode(!0).style.backgroundClip="",o.clearCloneStyle="content-box"===i.style.backgroundClip,h.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",h.appendChild(i),r.extend(o,{pixelPosition:function(){return b(),c},boxSizingReliable:function(){return b(),e},pixelMarginRight:function(){return b(),f},reliableMarginLeft:function(){return b(),g}}))}();function Ma(a,b,c){var d,e,f,g,h=a.style;return c=c||La(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||r.contains(a.ownerDocument,a)||(g=r.style(a,b)),!o.pixelMarginRight()&&Ka.test(g)&&Ja.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Na(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Oa=/^(none|table(?!-c[ea]).+)/,Pa={position:"absolute",visibility:"hidden",display:"block"},Qa={letterSpacing:"0",fontWeight:"400"},Ra=["Webkit","Moz","ms"],Sa=d.createElement("div").style;function Ta(a){if(a in Sa)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ra.length;while(c--)if(a=Ra[c]+b,a in Sa)return a}function Ua(a,b,c){var d=_.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Va(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;f<4;f+=2)"margin"===c&&(g+=r.css(a,c+aa[f],!0,e)),d?("content"===c&&(g-=r.css(a,"padding"+aa[f],!0,e)),"margin"!==c&&(g-=r.css(a,"border"+aa[f]+"Width",!0,e))):(g+=r.css(a,"padding"+aa[f],!0,e),"padding"!==c&&(g+=r.css(a,"border"+aa[f]+"Width",!0,e)));return g}function Wa(a,b,c){var d,e=!0,f=La(a),g="border-box"===r.css(a,"boxSizing",!1,f);if(a.getClientRects().length&&(d=a.getBoundingClientRect()[b]),d<=0||null==d){if(d=Ma(a,b,f),(d<0||null==d)&&(d=a.style[b]),Ka.test(d))return d;e=g&&(o.boxSizingReliable()||d===a.style[b]),d=parseFloat(d)||0}return d+Va(a,b,c||(g?"border":"content"),e,f)+"px"}r.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ma(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=r.camelCase(b),i=a.style;return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=_.exec(c))&&e[1]&&(c=da(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(r.cssNumber[h]?"":"px")),o.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=r.camelCase(b);return b=r.cssProps[h]||(r.cssProps[h]=Ta(h)||h),g=r.cssHooks[b]||r.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Ma(a,b,d)),"normal"===e&&b in Qa&&(e=Qa[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),r.each(["height","width"],function(a,b){r.cssHooks[b]={get:function(a,c,d){if(c)return!Oa.test(r.css(a,"display"))||a.getClientRects().length&&a.getBoundingClientRect().width?Wa(a,b,d):ca(a,Pa,function(){return Wa(a,b,d)})},set:function(a,c,d){var e,f=d&&La(a),g=d&&Va(a,b,d,"border-box"===r.css(a,"boxSizing",!1,f),f);return g&&(e=_.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=r.css(a,b)),Ua(a,c,g)}}}),r.cssHooks.marginLeft=Na(o.reliableMarginLeft,function(a,b){if(b)return(parseFloat(Ma(a,"marginLeft"))||a.getBoundingClientRect().left-ca(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px"}),r.each({margin:"",padding:"",border:"Width"},function(a,b){r.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];d<4;d++)e[a+aa[d]+b]=f[d]||f[d-2]||f[0];return e}},Ja.test(a)||(r.cssHooks[a+b].set=Ua)}),r.fn.extend({css:function(a,b){return S(this,function(a,b,c){var d,e,f={},g=0;if(r.isArray(b)){for(d=La(a),e=b.length;g<e;g++)f[b[g]]=r.css(a,b[g],!1,d);return f}return void 0!==c?r.style(a,b,c):r.css(a,b)},a,b,arguments.length>1)}});function Xa(a,b,c,d,e){return new Xa.prototype.init(a,b,c,d,e)}r.Tween=Xa,Xa.prototype={constructor:Xa,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Xa.propHooks[this.prop];return a&&a.get?a.get(this):Xa.propHooks._default.get(this)},run:function(a){var b,c=Xa.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Xa.propHooks._default.set(this),this}},Xa.prototype.init.prototype=Xa.prototype,Xa.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Xa.propHooks.scrollTop=Xa.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Xa.prototype.init,r.fx.step={};var Ya,Za,$a=/^(?:toggle|show|hide)$/,_a=/queueHooks$/;function ab(){Za&&(a.requestAnimationFrame(ab),r.fx.tick())}function bb(){return a.setTimeout(function(){Ya=void 0}),Ya=r.now()}function cb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=aa[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function db(a,b,c){for(var d,e=(gb.tweeners[b]||[]).concat(gb.tweeners["*"]),f=0,g=e.length;f<g;f++)if(d=e[f].call(c,b,a))return d}function eb(a,b,c){var d,e,f,g,h,i,j,k,l="width"in b||"height"in b,m=this,n={},o=a.style,p=a.nodeType&&ba(a),q=V.get(a,"fxshow");c.queue||(g=r._queueHooks(a,"fx"),null==g.unqueued&&(g.unqueued=0,h=g.empty.fire,g.empty.fire=function(){g.unqueued||h()}),g.unqueued++,m.always(function(){m.always(function(){g.unqueued--,r.queue(a,"fx").length||g.empty.fire()})}));for(d in b)if(e=b[d],$a.test(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}n[d]=q&&q[d]||r.style(a,d)}if(i=!r.isEmptyObject(b),i||!r.isEmptyObject(n)){l&&1===a.nodeType&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=q&&q.display,null==j&&(j=V.get(a,"display")),k=r.css(a,"display"),"none"===k&&(j?k=j:(ga([a],!0),j=a.style.display||j,k=r.css(a,"display"),ga([a]))),("inline"===k||"inline-block"===k&&null!=j)&&"none"===r.css(a,"float")&&(i||(m.done(function(){o.display=j}),null==j&&(k=o.display,j="none"===k?"":k)),o.display="inline-block")),c.overflow&&(o.overflow="hidden",m.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]})),i=!1;for(d in n)i||(q?"hidden"in q&&(p=q.hidden):q=V.access(a,"fxshow",{display:j}),f&&(q.hidden=!p),p&&ga([a],!0),m.done(function(){p||ga([a]),V.remove(a,"fxshow");for(d in n)r.style(a,d,n[d])})),i=db(p?q[d]:0,d,m),d in q||(q[d]=i.start,p&&(i.end=i.start,i.start=0))}}function fb(a,b){var c,d,e,f,g;for(c in a)if(d=r.camelCase(c),e=b[d],f=a[c],r.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=r.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function gb(a,b,c){var d,e,f=0,g=gb.prefilters.length,h=r.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Ya||bb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;g<i;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),f<1&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:r.extend({},b),opts:r.extend(!0,{specialEasing:{},easing:r.easing._default},c),originalProperties:b,originalOptions:c,startTime:Ya||bb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=r.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;c<d;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(fb(k,j.opts.specialEasing);f<g;f++)if(d=gb.prefilters[f].call(j,a,k,j.opts))return r.isFunction(d.stop)&&(r._queueHooks(j.elem,j.opts.queue).stop=r.proxy(d.stop,d)),d;return r.map(k,db,j),r.isFunction(j.opts.start)&&j.opts.start.call(a,j),r.fx.timer(r.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}r.Animation=r.extend(gb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return da(c.elem,a,_.exec(b),c),c}]},tweener:function(a,b){r.isFunction(a)?(b=a,a=["*"]):a=a.match(K);for(var c,d=0,e=a.length;d<e;d++)c=a[d],gb.tweeners[c]=gb.tweeners[c]||[],gb.tweeners[c].unshift(b)},prefilters:[eb],prefilter:function(a,b){b?gb.prefilters.unshift(a):gb.prefilters.push(a)}}),r.speed=function(a,b,c){var e=a&&"object"==typeof a?r.extend({},a):{complete:c||!c&&b||r.isFunction(a)&&a,duration:a,easing:c&&b||b&&!r.isFunction(b)&&b};return r.fx.off||d.hidden?e.duration=0:e.duration="number"==typeof e.duration?e.duration:e.duration in r.fx.speeds?r.fx.speeds[e.duration]:r.fx.speeds._default,null!=e.queue&&e.queue!==!0||(e.queue="fx"),e.old=e.complete,e.complete=function(){r.isFunction(e.old)&&e.old.call(this),e.queue&&r.dequeue(this,e.queue)},e},r.fn.extend({fadeTo:function(a,b,c,d){return this.filter(ba).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=r.isEmptyObject(a),f=r.speed(b,c,d),g=function(){var b=gb(this,r.extend({},a),f);(e||V.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=r.timers,g=V.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&_a.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||r.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=V.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=r.timers,g=d?d.length:0;for(c.finish=!0,r.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;b<g;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),r.each(["toggle","show","hide"],function(a,b){var c=r.fn[b];r.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(cb(b,!0),a,d,e)}}),r.each({slideDown:cb("show"),slideUp:cb("hide"),slideToggle:cb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){r.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),r.timers=[],r.fx.tick=function(){var a,b=0,c=r.timers;for(Ya=r.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||r.fx.stop(),Ya=void 0},r.fx.timer=function(a){r.timers.push(a),a()?r.fx.start():r.timers.pop()},r.fx.interval=13,r.fx.start=function(){Za||(Za=a.requestAnimationFrame?a.requestAnimationFrame(ab):a.setInterval(r.fx.tick,r.fx.interval))},r.fx.stop=function(){a.cancelAnimationFrame?a.cancelAnimationFrame(Za):a.clearInterval(Za),Za=null},r.fx.speeds={slow:600,fast:200,_default:400},r.fn.delay=function(b,c){return b=r.fx?r.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",o.checkOn=""!==a.value,o.optSelected=c.selected,a=d.createElement("input"),a.value="t",a.type="radio",o.radioValue="t"===a.value}();var hb,ib=r.expr.attrHandle;r.fn.extend({attr:function(a,b){return S(this,r.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?hb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);
+if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),hb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ib[b]||r.find.attr;ib[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=ib[g],ib[g]=e,e=null!=c(a,b,d)?g:null,ib[g]=f),e}});var jb=/^(?:input|select|textarea|button)$/i,kb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):jb.test(a.nodeName)||kb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});var lb=/[\t\r\n\f]/g;function mb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,mb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,mb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=mb(c),d=1===c.nodeType&&(" "+e+" ").replace(lb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=r.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,mb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=mb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(c)+" ").replace(lb," ").indexOf(b)>-1)return!0;return!1}});var nb=/\r/g,ob=/[\x20\t\r\n\f]+/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(nb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:r.trim(r.text(a)).replace(ob," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type,g=f?null:[],h=f?e+1:d.length,i=e<0?h:f?e:0;i<h;i++)if(c=d[i],(c.selected||i===e)&&!c.disabled&&(!c.parentNode.disabled||!r.nodeName(c.parentNode,"optgroup"))){if(b=r(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=r.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=r.inArray(r.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ha.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,""),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Qb=[],Rb=/(=)\?(?=&|$)|\?\?/;r.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Qb.pop()||r.expando+"_"+rb++;return this[a]=!0,a}}),r.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Rb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Rb.test(b.data)&&"data");if(h||"jsonp"===b.dataTypes[0])return e=b.jsonpCallback=r.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Rb,"$1"+e):b.jsonp!==!1&&(b.url+=(sb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||r.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?r(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Qb.push(e)),g&&r.isFunction(f)&&f(g[0]),g=f=void 0}),"script"}),o.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),r.parseHTML=function(a,b,c){if("string"!=typeof a)return[];"boolean"==typeof b&&(c=b,b=!1);var e,f,g;return b||(o.createHTMLDocument?(b=d.implementation.createHTMLDocument(""),e=b.createElement("base"),e.href=d.location.href,b.head.appendChild(e)):b=d),f=B.exec(a),g=!c&&[],f?[b.createElement(f[1])]:(f=oa([a],b,g),g&&g.length&&r(g).remove(),r.merge([],f.childNodes))},r.fn.load=function(a,b,c){var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=r.trim(a.slice(h)),a=a.slice(0,h)),r.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&r.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?r("<div>").append(r.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},r.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){r.fn[b]=function(a){return this.on(b,a)}}),r.expr.pseudos.animated=function(a){return r.grep(r.timers,function(b){return a===b.elem}).length};function Sb(a){return r.isWindow(a)?a:9===a.nodeType&&a.defaultView}r.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=r.css(a,"position"),l=r(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=r.css(a,"top"),i=r.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),r.isFunction(b)&&(b=b.call(a,c,r.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},r.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){r.offset.setOffset(this,a,b)});var b,c,d,e,f=this[0];if(f)return f.getClientRects().length?(d=f.getBoundingClientRect(),d.width||d.height?(e=f.ownerDocument,c=Sb(e),b=e.documentElement,{top:d.top+c.pageYOffset-b.clientTop,left:d.left+c.pageXOffset-b.clientLeft}):d):{top:0,left:0}},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===r.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),r.nodeName(a[0],"html")||(d=a.offset()),d={top:d.top+r.css(a[0],"borderTopWidth",!0),left:d.left+r.css(a[0],"borderLeftWidth",!0)}),{top:b.top-d.top-r.css(c,"marginTop",!0),left:b.left-d.left-r.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===r.css(a,"position"))a=a.offsetParent;return a||pa})}}),r.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;r.fn[a]=function(d){return S(this,function(a,d,e){var f=Sb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),r.each(["top","left"],function(a,b){r.cssHooks[b]=Na(o.pixelPosition,function(a,c){if(c)return c=Ma(a,b),Ka.test(c)?r(a).position()[b]+"px":c})}),r.each({Height:"height",Width:"width"},function(a,b){r.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){r.fn[d]=function(e,f){var g=arguments.length&&(c||"boolean"!=typeof e),h=c||(e===!0||f===!0?"margin":"border");return S(this,function(b,c,e){var f;return r.isWindow(b)?0===d.indexOf("outer")?b["inner"+a]:b.document.documentElement["client"+a]:9===b.nodeType?(f=b.documentElement,Math.max(b.body["scroll"+a],f["scroll"+a],b.body["offset"+a],f["offset"+a],f["client"+a])):void 0===e?r.css(b,c,h):r.style(b,c,e,h)},b,g?e:void 0,g)}})}),r.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),r.parseJSON=JSON.parse,"function"==typeof define&&define.amd&&define("jquery",[],function(){return r});var Tb=a.jQuery,Ub=a.$;return r.noConflict=function(b){return a.$===r&&(a.$=Ub),b&&a.jQuery===r&&(a.jQuery=Tb),r},b||(a.jQuery=a.$=r),r});
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.customShapes.min.js b/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.customShapes.min.js
new file mode 100644
index 0000000..3637688
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.customShapes.min.js
@@ -0,0 +1 @@
+(function(){"use strict";var a=[],b=function(b,c,d){a.push({name:b,drawShape:c,drawBorder:d})},c=function(){return a},d=function(a){return function(b,c,d,e,f,g){g.fillStyle=f,g.beginPath(),a(b,c,d,e,g),g.closePath(),g.fill()}},e=function(a){return function(b,c,d,e,f,g){g.strokeStyle=f,g.lineWidth=e/5,g.beginPath(),a(b,c,d,e,g),g.closePath(),g.stroke()}},f=function(a,b,c,d,e){var f=45*Math.PI/180;e.moveTo(b+d*Math.sin(f),c-d*Math.cos(f));for(var g=1;4>g;g++)e.lineTo(b+Math.sin(f+2*Math.PI*g/4)*d,c-Math.cos(f+2*Math.PI*g/4)*d)};b("square",d(f),e(f));var g=function(a,b,c,d,e){e.arc(b,c,d,0,2*Math.PI,!0)};b("circle",d(g),e(g));var h=function(a,b,c,d,e){e.moveTo(b-d,c),e.lineTo(b,c-d),e.lineTo(b+d,c),e.lineTo(b,c+d)};b("diamond",d(h),e(h));var i=function(a,b,c,d,e){var f=a.cross&&a.cross.lineWeight||5;e.moveTo(b-d,c-f),e.lineTo(b-d,c+f),e.lineTo(b-f,c+f),e.lineTo(b-f,c+d),e.lineTo(b+f,c+d),e.lineTo(b+f,c+f),e.lineTo(b+d,c+f),e.lineTo(b+d,c-f),e.lineTo(b+f,c-f),e.lineTo(b+f,c-d),e.lineTo(b-f,c-d),e.lineTo(b-f,c-f)};b("cross",d(i),e(i));var j=function(a,b,c,d,e){var f=a.equilateral&&a.equilateral.numPoints||5,g=(a.equilateral&&a.equilateral.rotate||0)*Math.PI/180,h=d;e.moveTo(b+h*Math.sin(g),c-h*Math.cos(g));for(var i=1;f>i;i++)e.lineTo(b+Math.sin(g+2*Math.PI*i/f)*h,c-Math.cos(g+2*Math.PI*i/f)*h)};b("equilateral",d(j),e(j));var k=function(a,b,c,d,e){var f=a.star&&a.star.numPoints||5,g=a.star&&a.star.innerRatio||.5,h=d,i=d*g,j=Math.PI/f;e.moveTo(b,c-d);for(var k=0;f>k;k++)e.lineTo(b+Math.sin(j+2*Math.PI*k/f)*i,c-Math.cos(j+2*Math.PI*k/f)*i),e.lineTo(b+Math.sin(2*Math.PI*(k+1)/f)*h,c-Math.cos(2*Math.PI*(k+1)/f)*h)};b("star",d(k),e(k));var l=function(a,b,c,d,e,f){f.fillStyle="yellow",f.beginPath(),f.arc(b,c,d,1.25*Math.PI,0,!1),f.arc(b,c,d,0,.75*Math.PI,!1),f.lineTo(b,c),f.closePath(),f.fill(),f.fillStyle="white",f.strokeStyle="black",f.beginPath(),f.arc(b+d/3,c-d/3,d/4,0,2*Math.PI,!1),f.closePath(),f.fill(),f.stroke(),f.fillStyle="black",f.beginPath(),f.arc(b+4*d/9,c-d/3,d/8,0,2*Math.PI,!1),f.closePath(),f.fill()};b("pacman",l,null),this.ShapeLibrary={enumerate:c,version:"0.1"}}).call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";if("undefined"==typeof ShapeLibrary)throw"ShapeLibrary is not declared";sigma.utils.pkg("sigma.canvas.nodes"),sigma.utils.pkg("sigma.svg.nodes");var b=a,c={},d=function(a){b=a},e=function(a,d,e,f,g){if(b&&a.image&&a.image.url){var h=a.image.url,i=a.image.h||1,j=a.image.w||1,k=a.image.scale||1,l=a.image.clip||1,m=c[h];m||(m=document.createElement("IMG"),m.src=h,m.status="loading",m.onerror=function(){console.log("error loading",h),m.status="error"},m.onload=function(){console.log("redraw on image load",h),m.status="ok",b.refresh()},c[h]=m);var n=i>j?j/i:1,o=j>i?i/j:1,p=f*k;g.save(),g.beginPath(),g.arc(d,e,f*l,0,2*Math.PI,!0),g.closePath(),g.clip(),"ok"===m.status&&g.drawImage(m,d+Math.sin(-0.7855)*p*n,e-Math.cos(-0.7855)*p*o,p*n*2*Math.sin(-0.7855)*-1,p*o*2*Math.cos(-0.7855)),g.restore()}},f=function(a,c,d){if(b&&a.image&&a.image.url){{var e=document.createElementNS(d("xmlns"),"circle"),f=document.createElementNS(d("xmlns"),"clipPath"),g=d("classPrefix")+"-clip-path-"+a.id,h=document.createElementNS(d("xmlns"),"defs"),i=document.createElementNS(d("xmlns"),"image");a.image.url}f.setAttributeNS(null,"id",g),f.appendChild(e),h.appendChild(f);var j=/MSIE [5-9]/.test(navigator.userAgent)?"":document.location.href;j=j.split("#")[0],i.setAttributeNS(null,"class",d("classPrefix")+"-node-image"),i.setAttributeNS(null,"clip-path","url("+j+"#"+g+")"),i.setAttributeNS(null,"pointer-events","none"),i.setAttributeNS("http://www.w3.org/1999/xlink","href",a.image.url),c.appendChild(h),c.appendChild(i)}},g=function(a,b,c){sigma.canvas.nodes[a]=function(a,d,f){var g=f("prefix")||"",h=a[g+"size"],i=a.color||f("defaultNodeColor"),j=a.borderColor||i,k=a[g+"x"],l=a[g+"y"];d.save(),b&&b(a,k,l,h,i,d),c&&c(a,k,l,h,j,d),e(a,k,l,h,d),d.restore()},sigma.svg.nodes[a]={create:function(a,b){var c=document.createElementNS(b("xmlns"),"g"),d=document.createElementNS(b("xmlns"),"circle");return c.setAttributeNS(null,"class",b("classPrefix")+"-node-group"),c.setAttributeNS(null,"data-node-id",a.id),d.setAttributeNS(null,"data-node-id",a.id),d.setAttributeNS(null,"class",b("classPrefix")+"-node"),d.setAttributeNS(null,"fill",a.color||b("defaultNodeColor")),c.appendChild(d),f(a,c,b),c},update:function(a,b,c){for(var d=c("classPrefix"),e=a.image.clip||1,f=a.image.h||1,g=a.image.w||1,h=c("prefix")||"",i=a.image.scale||1,j=a[h+"size"],k=a[h+"x"],l=a[h+"y"],m=i*j,n=f>g?g/f:1,o=g>f?f/g:1,p=0,q=b.childNodes;p<q.length;p++){var r=q[p].getAttribute("class");switch(r){case d+"-node":q[p].setAttributeNS(null,"cx",k),q[p].setAttributeNS(null,"cy",l),q[p].setAttributeNS(null,"r",j),c("freeStyle")||q[p].setAttributeNS(null,"fill",a.color||c("defaultNodeColor"));break;case d+"-node-image":q[p].setAttributeNS(null,"x",k+Math.sin(-0.7855)*m*n),q[p].setAttributeNS(null,"y",l-Math.cos(-0.7855)*m*o),q[p].setAttributeNS(null,"width",m*n*2*Math.sin(-0.7855)*-1),q[p].setAttributeNS(null,"height",m*o*2*Math.cos(-0.7855));break;default:var s=q[p].firstChild;if(null!=s){var t=d+"-clip-path-"+a.id;s.getAttribute("id")===t&&(s.firstChild.setAttributeNS(null,"cx",k),s.firstChild.setAttributeNS(null,"cy",l),s.firstChild.setAttributeNS(null,"r",e*j))}}}b.style.display=""}}};ShapeLibrary.enumerate().forEach(function(a){g(a.name,a.drawShape,a.drawBorder)}),this.CustomShapes={init:d,version:"0.1"}}.call(this);
\ No newline at end of file
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.edgeLabels.min.js b/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.edgeLabels.min.js
new file mode 100644
index 0000000..5b6d07b
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/plugins/sigma.renderers.edgeLabels.min.js
@@ -0,0 +1 @@
+(function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.settings");var a={defaultEdgeLabelColor:"#000",defaultEdgeLabelActiveColor:"#000",defaultEdgeLabelSize:10,edgeLabelSize:"fixed",edgeLabelSizePowRatio:1,edgeLabelThreshold:1};sigma.settings=sigma.utils.extend(sigma.settings||{},a),sigma.settings.drawEdgeLabels=!0}).call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.edges.labels"),sigma.canvas.edges.labels.curve=function(a,b,c,d,e){if("string"==typeof a.label){var f=e("prefix")||"",g=a[f+"size"]||1;if(!(g<e("edgeLabelThreshold"))){var h,i,j,k=b[f+"size"],l=b[f+"x"],m=b[f+"y"],n=c[f+"x"],o=c[f+"y"],p=n-l,q=o-m,r=n>l?1:-1,s={},t=.5;b.id===c.id?(s=sigma.utils.getSelfLoopControlPoints(l,m,k),i=sigma.utils.getPointOnBezierCurve(t,l,m,n,o,s.x1,s.y1,s.x2,s.y2),j=Math.atan2(1,1)):(s=sigma.utils.getQuadraticControlPoint(l,m,n,o),i=sigma.utils.getPointOnQuadraticCurve(t,l,m,n,o,s.x,s.y),j=Math.atan2(q*r,p*r)),h="fixed"===e("edgeLabelSize")?e("defaultEdgeLabelSize"):e("defaultEdgeLabelSize")*g*Math.pow(g,-1/e("edgeLabelSizePowRatio")),d.save(),a.active?(d.font=[e("activeFontStyle"),h+"px",e("activeFont")||e("font")].join(" "),d.fillStyle="edge"===e("edgeActiveColor")?a.active_color||e("defaultEdgeActiveColor"):e("defaultEdgeLabelActiveColor")):(d.font=[e("fontStyle"),h+"px",e("font")].join(" "),d.fillStyle="edge"===e("edgeLabelColor")?a.color||e("defaultEdgeColor"):e("defaultEdgeLabelColor")),d.textAlign="center",d.textBaseline="alphabetic",d.translate(i.x,i.y),d.rotate(j),d.fillText(a.label,0,-g/2-3),d.restore()}}}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.edges.labels"),sigma.canvas.edges.labels.curvedArrow=function(a,b,c,d,e){sigma.canvas.edges.labels.curve(a,b,c,d,e)}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.edges.labels"),sigma.canvas.edges.labels.def=function(a,b,c,d,e){if("string"==typeof a.label&&b!=c){var f=e("prefix")||"",g=a[f+"size"]||1;if(!(g<e("edgeLabelThreshold"))){if(0===e("edgeLabelSizePowRatio"))throw'"edgeLabelSizePowRatio" must not be 0.';var h,i=(b[f+"x"]+c[f+"x"])/2,j=(b[f+"y"]+c[f+"y"])/2,k=c[f+"x"]-b[f+"x"],l=c[f+"y"]-b[f+"y"],m=b[f+"x"]<c[f+"x"]?1:-1,n=Math.atan2(l*m,k*m);h="fixed"===e("edgeLabelSize")?e("defaultEdgeLabelSize"):e("defaultEdgeLabelSize")*g*Math.pow(g,-1/e("edgeLabelSizePowRatio")),d.save(),a.active?(d.font=[e("activeFontStyle"),h+"px",e("activeFont")||e("font")].join(" "),d.fillStyle="edge"===e("edgeActiveColor")?a.active_color||e("defaultEdgeActiveColor"):e("defaultEdgeLabelActiveColor")):(d.font=[e("fontStyle"),h+"px",e("font")].join(" "),d.fillStyle="edge"===e("edgeLabelColor")?a.color||e("defaultEdgeColor"):e("defaultEdgeLabelColor")),d.textAlign="center",d.textBaseline="alphabetic",d.translate(i,j),d.rotate(n),d.fillText(a.label,0,-g/2-3),d.restore()}}}}.call(this);
\ No newline at end of file
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.min.js b/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.min.js
new file mode 100644
index 0000000..a34250e
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.min.js
@@ -0,0 +1,5 @@
+/* sigma.js - A JavaScript library dedicated to graph drawing. - Version: 1.1.0 - Author: Alexis Jacomy, Sciences-Po Médialab - License: MIT */
+(function(a){"use strict";var b={},c=function(a){var d,e,f,g,h;c.classes.dispatcher.extend(this);var i=this,j=a||{};if("string"==typeof j||j instanceof HTMLElement?j={renderers:[j]}:"[object Array]"===Object.prototype.toString.call(j)&&(j={renderers:j}),g=j.renderers||j.renderer||j.container,j.renderers&&0!==j.renderers.length||("string"==typeof g||g instanceof HTMLElement||"object"==typeof g&&"container"in g)&&(j.renderers=[g]),j.id){if(b[j.id])throw'sigma: Instance "'+j.id+'" already exists.';Object.defineProperty(this,"id",{value:j.id})}else{for(h=0;b[h];)h++;Object.defineProperty(this,"id",{value:""+h})}for(b[this.id]=this,this.settings=new c.classes.configurable(c.settings,j.settings||{}),Object.defineProperty(this,"graph",{value:new c.classes.graph(this.settings),configurable:!0}),Object.defineProperty(this,"middlewares",{value:[],configurable:!0}),Object.defineProperty(this,"cameras",{value:{},configurable:!0}),Object.defineProperty(this,"renderers",{value:{},configurable:!0}),Object.defineProperty(this,"renderersPerCamera",{value:{},configurable:!0}),Object.defineProperty(this,"cameraFrames",{value:{},configurable:!0}),Object.defineProperty(this,"camera",{get:function(){return this.cameras[0]}}),Object.defineProperty(this,"events",{value:["click","rightClick","clickStage","doubleClickStage","rightClickStage","clickNode","clickNodes","doubleClickNode","doubleClickNodes","rightClickNode","rightClickNodes","overNode","overNodes","outNode","outNodes","downNode","downNodes","upNode","upNodes"],configurable:!0}),this._handler=function(a){var b,c={};for(b in a.data)c[b]=a.data[b];c.renderer=a.target,this.dispatchEvent(a.type,c)}.bind(this),f=j.renderers||[],d=0,e=f.length;e>d;d++)this.addRenderer(f[d]);for(f=j.middlewares||[],d=0,e=f.length;e>d;d++)this.middlewares.push("string"==typeof f[d]?c.middlewares[f[d]]:f[d]);"object"==typeof j.graph&&j.graph&&(this.graph.read(j.graph),this.refresh()),window.addEventListener("resize",function(){i.settings&&i.refresh()})};if(c.prototype.addCamera=function(b){var d,e=this;if(!arguments.length){for(b=0;this.cameras[""+b];)b++;b=""+b}if(this.cameras[b])throw'sigma.addCamera: The camera "'+b+'" already exists.';return d=new c.classes.camera(b,this.graph,this.settings),this.cameras[b]=d,d.quadtree=new c.classes.quad,c.classes.edgequad!==a&&(d.edgequadtree=new c.classes.edgequad),d.bind("coordinatesUpdated",function(){e.renderCamera(d,d.isAnimated)}),this.renderersPerCamera[b]=[],d},c.prototype.killCamera=function(a){if(a="string"==typeof a?this.cameras[a]:a,!a)throw"sigma.killCamera: The camera is undefined.";var b,c,d=this.renderersPerCamera[a.id];for(c=d.length,b=c-1;b>=0;b--)this.killRenderer(d[b]);return delete this.renderersPerCamera[a.id],delete this.cameraFrames[a.id],delete this.cameras[a.id],a.kill&&a.kill(),this},c.prototype.addRenderer=function(a){var b,d,e,f,g=a||{};if("string"==typeof g?g={container:document.getElementById(g)}:g instanceof HTMLElement&&(g={container:g}),"string"==typeof g.container&&(g.container=document.getElementById(g.container)),"id"in g)b=g.id;else{for(b=0;this.renderers[""+b];)b++;b=""+b}if(this.renderers[b])throw'sigma.addRenderer: The renderer "'+b+'" already exists.';if(d="function"==typeof g.type?g.type:c.renderers[g.type],d=d||c.renderers.def,e="camera"in g?g.camera instanceof c.classes.camera?g.camera:this.cameras[g.camera]||this.addCamera(g.camera):this.addCamera(),this.cameras[e.id]!==e)throw"sigma.addRenderer: The camera is not properly referenced.";return f=new d(this.graph,e,this.settings,g),this.renderers[b]=f,Object.defineProperty(f,"id",{value:b}),f.bind&&f.bind(["click","rightClick","clickStage","doubleClickStage","rightClickStage","clickNode","clickNodes","clickEdge","clickEdges","doubleClickNode","doubleClickNodes","doubleClickEdge","doubleClickEdges","rightClickNode","rightClickNodes","rightClickEdge","rightClickEdges","overNode","overNodes","overEdge","overEdges","outNode","outNodes","outEdge","outEdges","downNode","downNodes","downEdge","downEdges","upNode","upNodes","upEdge","upEdges"],this._handler),this.renderersPerCamera[e.id].push(f),f},c.prototype.killRenderer=function(a){if(a="string"==typeof a?this.renderers[a]:a,!a)throw"sigma.killRenderer: The renderer is undefined.";var b=this.renderersPerCamera[a.camera.id],c=b.indexOf(a);return c>=0&&b.splice(c,1),a.kill&&a.kill(),delete this.renderers[a.id],this},c.prototype.refresh=function(b){var d,e,f,g,h,i,j=0;for(b=b||{},g=this.middlewares||[],d=0,e=g.length;e>d;d++)g[d].call(this,0===d?"":"tmp"+j+":",d===e-1?"ready:":"tmp"+ ++j+":");for(f in this.cameras)h=this.cameras[f],h.settings("autoRescale")&&this.renderersPerCamera[h.id]&&this.renderersPerCamera[h.id].length?c.middlewares.rescale.call(this,g.length?"ready:":"",h.readPrefix,{width:this.renderersPerCamera[h.id][0].width,height:this.renderersPerCamera[h.id][0].height}):c.middlewares.copy.call(this,g.length?"ready:":"",h.readPrefix),b.skipIndexation||(i=c.utils.getBoundaries(this.graph,h.readPrefix),h.quadtree.index(this.graph.nodes(),{prefix:h.readPrefix,bounds:{x:i.minX,y:i.minY,width:i.maxX-i.minX,height:i.maxY-i.minY}}),h.edgequadtree!==a&&h.settings("drawEdges")&&h.settings("enableEdgeHovering")&&h.edgequadtree.index(this.graph,{prefix:h.readPrefix,bounds:{x:i.minX,y:i.minY,width:i.maxX-i.minX,height:i.maxY-i.minY}}));for(g=Object.keys(this.renderers),d=0,e=g.length;e>d;d++)if(this.renderers[g[d]].process)if(this.settings("skipErrors"))try{this.renderers[g[d]].process()}catch(k){console.log('Warning: The renderer "'+g[d]+'" crashed on ".process()"')}else this.renderers[g[d]].process();return this.render(),this},c.prototype.render=function(){var a,b,c;for(c=Object.keys(this.renderers),a=0,b=c.length;b>a;a++)if(this.settings("skipErrors"))try{this.renderers[c[a]].render()}catch(d){this.settings("verbose")&&console.log('Warning: The renderer "'+c[a]+'" crashed on ".render()"')}else this.renderers[c[a]].render();return this},c.prototype.renderCamera=function(a,b){var c,d,e,f=this;if(b)for(e=this.renderersPerCamera[a.id],c=0,d=e.length;d>c;c++)if(this.settings("skipErrors"))try{e[c].render()}catch(g){this.settings("verbose")&&console.log('Warning: The renderer "'+e[c].id+'" crashed on ".render()"')}else e[c].render();else if(!this.cameraFrames[a.id]){for(e=this.renderersPerCamera[a.id],c=0,d=e.length;d>c;c++)if(this.settings("skipErrors"))try{e[c].render()}catch(g){this.settings("verbose")&&console.log('Warning: The renderer "'+e[c].id+'" crashed on ".render()"')}else e[c].render();this.cameraFrames[a.id]=requestAnimationFrame(function(){delete f.cameraFrames[a.id]})}return this},c.prototype.kill=function(){var a;this.dispatchEvent("kill"),this.graph.kill(),delete this.middlewares;for(a in this.renderers)this.killRenderer(this.renderers[a]);for(a in this.cameras)this.killCamera(this.cameras[a]);delete this.renderers,delete this.cameras;for(a in this)this.hasOwnProperty(a)&&delete this[a];delete b[this.id]},c.instances=function(a){return arguments.length?b[a]:c.utils.extend({},b)},c.version="1.1.0","undefined"!=typeof this.sigma)throw"An object called sigma is already in the global scope.";this.sigma=c}).call(this),function(a){"use strict";function b(a,c){var d,e,f,g;if(arguments.length)if(1===arguments.length&&Object(arguments[0])===arguments[0])for(a in arguments[0])b(a,arguments[0][a]);else if(arguments.length>1)for(g=Array.isArray(a)?a:a.split(/ /),d=0,e=g.length;d!==e;d+=1)f=g[d],C[f]||(C[f]=[]),C[f].push({handler:c})}function c(a,b){var c,d,e,f,g,h,i=Array.isArray(a)?a:a.split(/ /);if(arguments.length)if(b)for(c=0,d=i.length;c!==d;c+=1){if(h=i[c],C[h]){for(g=[],e=0,f=C[h].length;e!==f;e+=1)C[h][e].handler!==b&&g.push(C[h][e]);C[h]=g}C[h]&&0===C[h].length&&delete C[h]}else for(c=0,d=i.length;c!==d;c+=1)delete C[i[c]];else C=Object.create(null)}function d(a,b){var c,d,e,f,g,h,i=Array.isArray(a)?a:a.split(/ /);for(b=void 0===b?{}:b,c=0,e=i.length;c!==e;c+=1)if(h=i[c],C[h])for(g={type:h,data:b||{}},d=0,f=C[h].length;d!==f;d+=1)try{C[h][d].handler(g)}catch(j){}}function e(){var a,b,c,d,e=!1,f=s(),g=x.shift();if(c=g.job(),f=s()-f,g.done++,g.time+=f,g.currentTime+=f,g.weightTime=g.currentTime/(g.weight||1),g.averageTime=g.time/g.done,d=g.count?g.count<=g.done:!c,!d){for(a=0,b=x.length;b>a;a++)if(x[a].weightTime>g.weightTime){x.splice(a,0,g),e=!0;break}e||x.push(g)}return d?g:null}function f(a){var b=x.length;w[a.id]=a,a.status="running",b&&(a.weightTime=x[b-1].weightTime,a.currentTime=a.weightTime*(a.weight||1)),a.startTime=s(),d("jobStarted",q(a)),x.push(a)}function g(){var a,b,c;for(a in v)b=v[a],b.after?y[a]=b:f(b),delete v[a];for(u=!!x.length;x.length&&s()-t<B.frameDuration;)if(c=e()){i(c.id);for(a in y)y[a].after===c.id&&(f(y[a]),delete y[a])}u?(t=s(),d("enterFrame"),setTimeout(g,0)):d("stop")}function h(a,b){var c,e,f;if(Array.isArray(a)){for(A=!0,c=0,e=a.length;e>c;c++)h(a[c].id,p(a[c],b));A=!1,u||(t=s(),d("start"),g())}else if("object"==typeof a)if("string"==typeof a.id)h(a.id,a);else{A=!0;for(c in a)"function"==typeof a[c]?h(c,p({job:a[c]},b)):h(c,p(a[c],b));A=!1,u||(t=s(),d("start"),g())}else{if("string"!=typeof a)throw new Error("[conrad.addJob] Wrong arguments.");if(k(a))throw new Error('[conrad.addJob] Job with id "'+a+'" already exists.');if("function"==typeof b)f={id:a,done:0,time:0,status:"waiting",currentTime:0,averageTime:0,weightTime:0,job:b};else{if("object"!=typeof b)throw new Error("[conrad.addJob] Wrong arguments.");f=p({id:a,done:0,time:0,status:"waiting",currentTime:0,averageTime:0,weightTime:0},b)}v[a]=f,d("jobAdded",q(f)),u||A||(t=s(),d("start"),g())}return this}function i(a){var b,c,e,f,g=!1;if(Array.isArray(a))for(b=0,c=a.length;c>b;b++)i(a[b]);else{if("string"!=typeof a)throw new Error("[conrad.killJob] Wrong arguments.");for(e=[w,y,v],b=0,c=e.length;c>b;b++)a in e[b]&&(f=e[b][a],B.history&&(f.status="done",z.push(f)),d("jobEnded",q(f)),delete e[b][a],"function"==typeof f.end&&f.end(),g=!0);for(e=x,b=0,c=e.length;c>b;b++)if(e[b].id===a){e.splice(b,1);break}if(!g)throw new Error('[conrad.killJob] Job "'+a+'" not found.')}return this}function j(){var a,b=p(v,w,y);if(B.history)for(a in b)b[a].status="done",z.push(b[a]),"function"==typeof b[a].end&&b[a].end();return v={},y={},w={},x=[],u=!1,this}function k(a){var b=v[a]||w[a]||y[a];return b?p(b):null}function l(){var a;if("string"==typeof a1&&1===arguments.length)return B[a1];a="object"==typeof a1&&1===arguments.length?a1||{}:{},"string"==typeof a1&&(a[a1]=a2);for(var b in a)void 0!==a[b]?B[b]=a[b]:delete B[b];return this}function m(){return u}function n(){return z=[],this}function o(a,b){var c,d,e,f,g,h,i;if(!arguments.length){g=[];for(d in v)g.push(v[d]);for(d in y)g.push(y[d]);for(d in w)g.push(w[d]);g=g.concat(z)}if("string"==typeof a)switch(a){case"waiting":g=r(y);break;case"running":g=r(w);break;case"done":g=z;break;default:h=a}if(a instanceof RegExp&&(h=a),!h&&("string"==typeof b||b instanceof RegExp)&&(h=b),h){if(i="string"==typeof h,g instanceof Array)c=g;else if("object"==typeof g){c=[];for(d in g)c=c.concat(g[d])}else{c=[];for(d in v)c.push(v[d]);for(d in y)c.push(y[d]);for(d in w)c.push(w[d]);c=c.concat(z)}for(g=[],e=0,f=c.length;f>e;e++)(i?c[e].id===h:c[e].id.match(h))&&g.push(c[e])}return q(g)}function p(){var a,b,c={},d=arguments.length;for(a=d-1;a>=0;a--)for(b in arguments[a])c[b]=arguments[a][b];return c}function q(a){var b,c,d;if(!a)return a;if(Array.isArray(a))for(b=[],c=0,d=a.length;d>c;c++)b.push(q(a[c]));else if("object"==typeof a){b={};for(c in a)b[c]=q(a[c])}else b=a;return b}function r(a){var b,c=[];for(b in a)c.push(a[b]);return c}function s(){return Date.now?Date.now():(new Date).getTime()}if(a.conrad)throw new Error("conrad already exists");var t,u=!1,v={},w={},x=[],y={},z=[],A=!1,B={frameDuration:20,history:!0},C=Object.create(null);Array.isArray||(Array.isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)});var D={hasJob:k,addJob:h,killJob:i,killAll:j,settings:l,getStats:o,isRunning:m,clearHistory:n,bind:b,unbind:c,version:"0.1.0"};"undefined"!=typeof exports&&("undefined"!=typeof module&&module.exports&&(exports=module.exports=D),exports.conrad=D),a.conrad=D}(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";var b=this;sigma.utils=sigma.utils||{},sigma.utils.extend=function(){var a,b,c={},d=arguments.length;for(a=d-1;a>=0;a--)for(b in arguments[a])c[b]=arguments[a][b];return c},sigma.utils.dateNow=function(){return Date.now?Date.now():(new Date).getTime()},sigma.utils.pkg=function(a){return(a||"").split(".").reduce(function(a,b){return b in a?a[b]:a[b]={}},b)},sigma.utils.id=function(){var a=0;return function(){return++a}}();var c={};sigma.utils.floatColor=function(a){if(c[a])return c[a];var b=a,d=0,e=0,f=0;"#"===a[0]?(a=a.slice(1),3===a.length?(d=parseInt(a.charAt(0)+a.charAt(0),16),e=parseInt(a.charAt(1)+a.charAt(1),16),f=parseInt(a.charAt(2)+a.charAt(2),16)):(d=parseInt(a.charAt(0)+a.charAt(1),16),e=parseInt(a.charAt(2)+a.charAt(3),16),f=parseInt(a.charAt(4)+a.charAt(5),16))):a.match(/^ *rgba? *\(/)&&(a=a.match(/^ *rgba? *\( *([0-9]*) *, *([0-9]*) *, *([0-9]*) *(,.*)?\) *$/),d=+a[1],e=+a[2],f=+a[3]);var g=256*d*256+256*e+f;return c[b]=g,g},sigma.utils.zoomTo=function(a,b,c,d,e){var f,g,h,i=a.settings;g=Math.max(i("zoomMin"),Math.min(i("zoomMax"),a.ratio*d)),g!==a.ratio&&(d=g/a.ratio,h={x:b*(1-d)+a.x,y:c*(1-d)+a.y,ratio:g},e&&e.duration?(f=sigma.misc.animation.killAll(a),e=sigma.utils.extend(e,{easing:f?"quadraticOut":"quadraticInOut"}),sigma.misc.animation.camera(a,h,e)):(a.goTo(h),e&&e.onComplete&&e.onComplete()))},sigma.utils.getQuadraticControlPoint=function(a,b,c,d){return{x:(a+c)/2+(d-b)/4,y:(b+d)/2+(a-c)/4}},sigma.utils.getPointOnQuadraticCurve=function(a,b,c,d,e,f,g){return{x:Math.pow(1-a,2)*b+2*(1-a)*a*f+Math.pow(a,2)*d,y:Math.pow(1-a,2)*c+2*(1-a)*a*g+Math.pow(a,2)*e}},sigma.utils.getPointOnBezierCurve=function(a,b,c,d,e,f,g,h,i){var j=Math.pow(1-a,3),k=3*a*Math.pow(1-a,2),l=3*Math.pow(a,2)*(1-a),m=Math.pow(a,3);return{x:j*b+k*f+l*h+m*d,y:j*c+k*g+l*i+m*e}},sigma.utils.getSelfLoopControlPoints=function(a,b,c){return{x1:a-7*c,y1:b,x2:a,y2:b+7*c}},sigma.utils.getDistance=function(a,b,c,d){return Math.sqrt(Math.pow(c-a,2)+Math.pow(d-b,2))},sigma.utils.getCircleIntersection=function(a,b,c,d,e,f){var g,h,i,j,k,l,m,n,o;if(h=d-a,i=e-b,j=Math.sqrt(i*i+h*h),j>c+f)return!1;if(j<Math.abs(c-f))return!1;g=(c*c-f*f+j*j)/(2*j),n=a+h*g/j,o=b+i*g/j,k=Math.sqrt(c*c-g*g),l=-i*(k/j),m=h*(k/j);var p=n+l,q=n-l,r=o+m,s=o-m;return{xi:p,xi_prime:q,yi:r,yi_prime:s}},sigma.utils.isPointOnSegment=function(a,b,c,d,e,f,g){var h=Math.abs((b-d)*(e-c)-(a-c)*(f-d)),i=sigma.utils.getDistance(c,d,e,f),j=h/i;return g>j&&Math.min(c,e)<=a&&a<=Math.max(c,e)&&Math.min(d,f)<=b&&b<=Math.max(d,f)},sigma.utils.isPointOnQuadraticCurve=function(a,b,c,d,e,f,g,h,i){var j=sigma.utils.getDistance(c,d,e,f);if(Math.abs(a-c)>j||Math.abs(b-d)>j)return!1;for(var k,l=sigma.utils.getDistance(a,b,c,d),m=sigma.utils.getDistance(a,b,e,f),n=.5,o=m>l?-.01:.01,p=.001,q=100,r=sigma.utils.getPointOnQuadraticCurve(n,c,d,e,f,g,h),s=sigma.utils.getDistance(a,b,r.x,r.y);q-->0&&n>=0&&1>=n&&s>i&&(o>p||-p>o);)k=s,r=sigma.utils.getPointOnQuadraticCurve(n,c,d,e,f,g,h),s=sigma.utils.getDistance(a,b,r.x,r.y),s>k?(o=-o/2,n+=o):0>n+o||n+o>1?(o/=2,s=k):n+=o;return i>s},sigma.utils.isPointOnBezierCurve=function(a,b,c,d,e,f,g,h,i,j,k){var l=sigma.utils.getDistance(c,d,g,h);if(Math.abs(a-c)>l||Math.abs(b-d)>l)return!1;for(var m,n=sigma.utils.getDistance(a,b,c,d),o=sigma.utils.getDistance(a,b,e,f),p=.5,q=o>n?-.01:.01,r=.001,s=100,t=sigma.utils.getPointOnBezierCurve(p,c,d,e,f,g,h,i,j),u=sigma.utils.getDistance(a,b,t.x,t.y);s-->0&&p>=0&&1>=p&&u>k&&(q>r||-r>q);)m=u,t=sigma.utils.getPointOnBezierCurve(p,c,d,e,f,g,h,i,j),u=sigma.utils.getDistance(a,b,t.x,t.y),u>m?(q=-q/2,p+=q):0>p+q||p+q>1?(q/=2,u=m):p+=q;return k>u},sigma.utils.getX=function(b){return b.offsetX!==a&&b.offsetX||b.layerX!==a&&b.layerX||b.clientX!==a&&b.clientX},sigma.utils.getY=function(b){return b.offsetY!==a&&b.offsetY||b.layerY!==a&&b.layerY||b.clientY!==a&&b.clientY},sigma.utils.getPixelRatio=function(){var b=1;return window.screen.deviceXDPI!==a&&window.screen.logicalXDPI!==a&&window.screen.deviceXDPI>window.screen.logicalXDPI?b=window.screen.systemXDPI/window.screen.logicalXDPI:window.devicePixelRatio!==a&&(b=window.devicePixelRatio),b},sigma.utils.getWidth=function(b){var c=b.target.ownerSVGElement?b.target.ownerSVGElement.width:b.target.width;return"number"==typeof c&&c||c!==a&&c.baseVal!==a&&c.baseVal.value},sigma.utils.getCenter=function(a){var b=-1!==a.target.namespaceURI.indexOf("svg")?1:sigma.utils.getPixelRatio();return{x:sigma.utils.getWidth(a)/(2*b),y:sigma.utils.getHeight(a)/(2*b)}},sigma.utils.mouseCoords=function(a,b,c){return b=b||sigma.utils.getX(a),c=c||sigma.utils.getY(a),{x:b-sigma.utils.getCenter(a).x,y:c-sigma.utils.getCenter(a).y,clientX:a.clientX,clientY:a.clientY,ctrlKey:a.ctrlKey,metaKey:a.metaKey,altKey:a.altKey,shiftKey:a.shiftKey}},sigma.utils.getHeight=function(b){var c=b.target.ownerSVGElement?b.target.ownerSVGElement.height:b.target.height;return"number"==typeof c&&c||c!==a&&c.baseVal!==a&&c.baseVal.value},sigma.utils.getDelta=function(b){return b.wheelDelta!==a&&b.wheelDelta||b.detail!==a&&-b.detail},sigma.utils.getOffset=function(a){for(var b=0,c=0;a;)c+=parseInt(a.offsetTop),b+=parseInt(a.offsetLeft),a=a.offsetParent;return{top:c,left:b}},sigma.utils.doubleClick=function(a,b,c){var d,e=0;a._doubleClickHandler=a._doubleClickHandler||{},a._doubleClickHandler[b]=a._doubleClickHandler[b]||[],d=a._doubleClickHandler[b],d.push(function(a){return e++,2===e?(e=0,c(a)):void(1===e&&setTimeout(function(){e=0},sigma.settings.doubleClickTimeout))}),a.addEventListener(b,d[d.length-1],!1)},sigma.utils.unbindDoubleClick=function(a,b){for(var c,d=(a._doubleClickHandler||{})[b]||[];c=d.pop();)a.removeEventListener(b,c);delete(a._doubleClickHandler||{})[b]},sigma.utils.easings=sigma.utils.easings||{},sigma.utils.easings.linearNone=function(a){return a},sigma.utils.easings.quadraticIn=function(a){return a*a},sigma.utils.easings.quadraticOut=function(a){return a*(2-a)},sigma.utils.easings.quadraticInOut=function(a){return(a*=2)<1?.5*a*a:-.5*(--a*(a-2)-1)},sigma.utils.easings.cubicIn=function(a){return a*a*a},sigma.utils.easings.cubicOut=function(a){return--a*a*a+1},sigma.utils.easings.cubicInOut=function(a){return(a*=2)<1?.5*a*a*a:.5*((a-=2)*a*a+2)},sigma.utils.loadShader=function(a,b,c,d){var e,f=a.createShader(c);return a.shaderSource(f,b),a.compileShader(f),e=a.getShaderParameter(f,a.COMPILE_STATUS),e?f:(d&&d('Error compiling shader "'+f+'":'+a.getShaderInfoLog(f)),a.deleteShader(f),null)},sigma.utils.loadProgram=function(a,b,c,d,e){var f,g,h=a.createProgram();for(f=0;f<b.length;++f)a.attachShader(h,b[f]);if(c)for(f=0;f<c.length;++f)a.bindAttribLocation(h,locations?locations[f]:f,opt_attribs[f]);return a.linkProgram(h),g=a.getProgramParameter(h,a.LINK_STATUS),g?h:(e&&e("Error in program linking: "+a.getProgramInfoLog(h)),a.deleteProgram(h),null)},sigma.utils.pkg("sigma.utils.matrices"),sigma.utils.matrices.translation=function(a,b){return[1,0,0,0,1,0,a,b,1]},sigma.utils.matrices.rotation=function(a,b){var c=Math.cos(a),d=Math.sin(a);return b?[c,-d,d,c]:[c,-d,0,d,c,0,0,0,1]},sigma.utils.matrices.scale=function(a,b){return b?[a,0,0,a]:[a,0,0,0,a,0,0,0,1]},sigma.utils.matrices.multiply=function(a,b,c){var d=c?2:3,e=a[0*d+0],f=a[0*d+1],g=a[0*d+2],h=a[1*d+0],i=a[1*d+1],j=a[1*d+2],k=a[2*d+0],l=a[2*d+1],m=a[2*d+2],n=b[0*d+0],o=b[0*d+1],p=b[0*d+2],q=b[1*d+0],r=b[1*d+1],s=b[1*d+2],t=b[2*d+0],u=b[2*d+1],v=b[2*d+2];return c?[e*n+f*q,e*o+f*r,h*n+i*q,h*o+i*r]:[e*n+f*q+g*t,e*o+f*r+g*u,e*p+f*s+g*v,h*n+i*q+j*t,h*o+i*r+j*u,h*p+i*s+j*v,k*n+l*q+m*t,k*o+l*r+m*u,k*p+l*s+m*v]}}.call(this),function(a){"use strict";var b,c=0,d=["ms","moz","webkit","o"];for(b=0;b<d.length&&!a.requestAnimationFrame;b++)a.requestAnimationFrame=a[d[b]+"RequestAnimationFrame"],a.cancelAnimationFrame=a[d[b]+"CancelAnimationFrame"]||a[d[b]+"CancelRequestAnimationFrame"];a.requestAnimationFrame||(a.requestAnimationFrame=function(b){var d=(new Date).getTime(),e=Math.max(0,16-(d-c)),f=a.setTimeout(function(){b(d+e)},e);return c=d+e,f}),a.cancelAnimationFrame||(a.cancelAnimationFrame=function(a){clearTimeout(a)}),Function.prototype.bind||(Function.prototype.bind=function(a){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var b,c,d=Array.prototype.slice.call(arguments,1),e=this;return b=function(){},c=function(){return e.apply(this instanceof b&&a?this:a,d.concat(Array.prototype.slice.call(arguments)))},b.prototype=this.prototype,c.prototype=new b,c})}(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.settings");var a={clone:!0,immutable:!0,verbose:!1,classPrefix:"sigma",defaultNodeType:"def",defaultEdgeType:"def",defaultLabelColor:"#000",defaultEdgeColor:"#000",defaultNodeColor:"#000",defaultLabelSize:14,edgeColor:"source",minArrowSize:0,font:"arial",fontStyle:"",labelColor:"default",labelSize:"fixed",labelSizeRatio:1,labelThreshold:8,webglOversamplingRatio:2,borderSize:0,defaultNodeBorderColor:"#000",hoverFont:"",singleHover:!0,hoverFontStyle:"",labelHoverShadow:"default",labelHoverShadowColor:"#000",nodeHoverColor:"node",defaultNodeHoverColor:"#000",labelHoverBGColor:"default",defaultHoverLabelBGColor:"#fff",labelHoverColor:"default",defaultLabelHoverColor:"#000",edgeHoverColor:"edge",edgeHoverSizeRatio:1,defaultEdgeHoverColor:"#000",edgeHoverExtremities:!1,drawEdges:!0,drawNodes:!0,drawLabels:!0,drawEdgeLabels:!1,batchEdgesDrawing:!1,hideEdgesOnMove:!1,canvasEdgesBatchSize:500,webglEdgesBatchSize:1e3,scalingMode:"inside",sideMargin:0,minEdgeSize:.5,maxEdgeSize:1,minNodeSize:1,maxNodeSize:8,touchEnabled:!0,mouseEnabled:!0,mouseWheelEnabled:!0,doubleClickEnabled:!0,eventsEnabled:!0,zoomingRatio:1.7,doubleClickZoomingRatio:2.2,zoomMin:.0625,zoomMax:2,mouseZoomDuration:200,doubleClickZoomDuration:200,mouseInertiaDuration:200,mouseInertiaRatio:3,touchInertiaDuration:200,touchInertiaRatio:3,doubleClickTimeout:300,doubleTapTimeout:300,dragTimeout:200,autoResize:!0,autoRescale:!0,enableCamera:!0,enableHovering:!0,enableEdgeHovering:!1,edgeHoverPrecision:5,rescaleIgnoreSize:!1,skipErrors:!1,nodesPowRatio:.5,edgesPowRatio:.5,animationsTime:200};sigma.settings=sigma.utils.extend(sigma.settings||{},a)}.call(this),function(){"use strict";var a=function(){Object.defineProperty(this,"_handlers",{value:{}})};a.prototype.bind=function(a,b){var c,d,e,f;if(1===arguments.length&&"object"==typeof arguments[0])for(a in arguments[0])this.bind(a,arguments[0][a]);else{if(2!==arguments.length||"function"!=typeof arguments[1])throw"bind: Wrong arguments.";for(f="string"==typeof a?a.split(" "):a,c=0,d=f.length;c!==d;c+=1)e=f[c],e&&(this._handlers[e]||(this._handlers[e]=[]),this._handlers[e].push({handler:b}))}return this},a.prototype.unbind=function(a,b){var c,d,e,f,g,h,i,j="string"==typeof a?a.split(" "):a;if(!arguments.length){for(g in this._handlers)delete this._handlers[g];return this}if(b)for(c=0,d=j.length;c!==d;c+=1){if(i=j[c],this._handlers[i]){for(h=[],e=0,f=this._handlers[i].length;e!==f;e+=1)this._handlers[i][e].handler!==b&&h.push(this._handlers[i][e]);this._handlers[i]=h}this._handlers[i]&&0===this._handlers[i].length&&delete this._handlers[i]}else for(c=0,d=j.length;c!==d;c+=1)delete this._handlers[j[c]];return this},a.prototype.dispatchEvent=function(a,b){var c,d,e,f,g,h,i,j=this,k="string"==typeof a?a.split(" "):a;for(b=void 0===b?{}:b,c=0,d=k.length;c!==d;c+=1)if(i=k[c],this._handlers[i]){for(h=j.getEvent(i,b),g=[],e=0,f=this._handlers[i].length;e!==f;e+=1)this._handlers[i][e].handler(h),this._handlers[i][e].one||g.push(this._handlers[i][e]);this._handlers[i]=g}return this},a.prototype.getEvent=function(a,b){return{type:a,data:b||{},target:this}},a.extend=function(b,c){var d;for(d in a.prototype)a.prototype.hasOwnProperty(d)&&(b[d]=a.prototype[d]);a.apply(b,c)},"undefined"!=typeof this.sigma?(this.sigma.classes=this.sigma.classes||{},this.sigma.classes.dispatcher=a):"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=a),exports.dispatcher=a):this.dispatcher=a}.call(this),function(){"use strict";var a=function(){var b,c,d={},e=Array.prototype.slice.call(arguments,0),f=function(a,b){var c,g,h,i;if(1===arguments.length&&"string"==typeof a){if(void 0!==d[a])return d[a];for(g=0,h=e.length;h>g;g++)if(void 0!==e[g][a])return e[g][a];return void 0}if("object"==typeof a&&"string"==typeof b)return void 0!==(a||{})[b]?a[b]:f(b);for(c="object"==typeof a&&void 0===b?a:{},"string"==typeof a&&(c[a]=b),g=0,i=Object.keys(c),h=i.length;h>g;g++)d[i[g]]=c[i[g]];return this};for(f.embedObjects=function(){var b=e.concat(d).concat(Array.prototype.splice.call(arguments,0));return a.apply({},b)},b=0,c=arguments.length;c>b;b++)f(arguments[b]);return f};"undefined"!=typeof this.sigma?(this.sigma.classes=this.sigma.classes||{},this.sigma.classes.configurable=a):"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=a),exports.configurable=a):this.configurable=a}.call(this),function(){"use strict";function a(a,b,c){var d=function(){var d,e;for(d in g[a])g[a][d].apply(b,arguments);e=c.apply(b,arguments);for(d in f[a])f[a][d].apply(b,arguments);return e};return d}function b(a){var b;for(b in a)"hasOwnProperty"in a&&!a.hasOwnProperty(b)||delete a[b];return a}var c=Object.create(null),d=Object.create(null),e=Object.create(null),f=Object.create(null),g=Object.create(null),h={immutable:!0,clone:!0},i=function(a){return h[a]},j=function(b){var d,f,g;g={settings:b||i,nodesArray:[],edgesArray:[],nodesIndex:Object.create(null),edgesIndex:Object.create(null),inNeighborsIndex:Object.create(null),outNeighborsIndex:Object.create(null),allNeighborsIndex:Object.create(null),inNeighborsCount:Object.create(null),outNeighborsCount:Object.create(null),allNeighborsCount:Object.create(null)};for(d in e)e[d].call(g);for(d in c)f=a(d,g,c[d]),this[d]=f,g[d]=f};j.addMethod=function(a,b){if("string"!=typeof a||"function"!=typeof b||2!==arguments.length)throw"addMethod: Wrong arguments.";if(c[a]||j[a])throw'The method "'+a+'" already exists.';return c[a]=b,f[a]=Object.create(null),g[a]=Object.create(null),this},j.hasMethod=function(a){return!(!c[a]&&!j[a])},j.attach=function(a,b,c,d){if("string"!=typeof a||"string"!=typeof b||"function"!=typeof c||arguments.length<3||arguments.length>4)throw"attach: Wrong arguments.";var h;if("constructor"===a)h=e;else if(d){if(!g[a])throw'The method "'+a+'" does not exist.';h=g[a]}else{if(!f[a])throw'The method "'+a+'" does not exist.';h=f[a]}if(h[b])throw'A function "'+b+'" is already attached to the method "'+a+'".';return h[b]=c,this},j.attachBefore=function(a,b,c){return this.attach(a,b,c,!0)},j.addIndex=function(a,b){if("string"!=typeof a||Object(b)!==b||2!==arguments.length)throw"addIndex: Wrong arguments.";if(d[a])throw'The index "'+a+'" already exists.';var c;d[a]=b;for(c in b){if("function"!=typeof b[c])throw"The bindings must be functions.";j.attach(c,a,b[c])}return this},j.addMethod("addNode",function(a){if(Object(a)!==a||1!==arguments.length)throw"addNode: Wrong arguments.";if("string"!=typeof a.id&&"number"!=typeof a.id)throw"The node must have a string or number id.";if(this.nodesIndex[a.id])throw'The node "'+a.id+'" already exists.';var b,c=a.id,d=Object.create(null);if(this.settings("clone"))for(b in a)"id"!==b&&(d[b]=a[b]);else d=a;return this.settings("immutable")?Object.defineProperty(d,"id",{value:c,enumerable:!0}):d.id=c,this.inNeighborsIndex[c]=Object.create(null),this.outNeighborsIndex[c]=Object.create(null),this.allNeighborsIndex[c]=Object.create(null),this.inNeighborsCount[c]=0,this.outNeighborsCount[c]=0,this.allNeighborsCount[c]=0,this.nodesArray.push(d),this.nodesIndex[d.id]=d,this}),j.addMethod("addEdge",function(a){if(Object(a)!==a||1!==arguments.length)throw"addEdge: Wrong arguments.";if("string"!=typeof a.id&&"number"!=typeof a.id)throw"The edge must have a string or number id.";if("string"!=typeof a.source&&"number"!=typeof a.source||!this.nodesIndex[a.source])throw"The edge source must have an existing node id.";if("string"!=typeof a.target&&"number"!=typeof a.target||!this.nodesIndex[a.target])throw"The edge target must have an existing node id.";if(this.edgesIndex[a.id])throw'The edge "'+a.id+'" already exists.';var b,c=Object.create(null);if(this.settings("clone"))for(b in a)"id"!==b&&"source"!==b&&"target"!==b&&(c[b]=a[b]);else c=a;return this.settings("immutable")?(Object.defineProperty(c,"id",{value:a.id,enumerable:!0}),Object.defineProperty(c,"source",{value:a.source,enumerable:!0}),Object.defineProperty(c,"target",{value:a.target,enumerable:!0})):(c.id=a.id,c.source=a.source,c.target=a.target),this.edgesArray.push(c),this.edgesIndex[c.id]=c,this.inNeighborsIndex[c.target][c.source]||(this.inNeighborsIndex[c.target][c.source]=Object.create(null)),this.inNeighborsIndex[c.target][c.source][c.id]=c,this.outNeighborsIndex[c.source][c.target]||(this.outNeighborsIndex[c.source][c.target]=Object.create(null)),this.outNeighborsIndex[c.source][c.target][c.id]=c,this.allNeighborsIndex[c.source][c.target]||(this.allNeighborsIndex[c.source][c.target]=Object.create(null)),this.allNeighborsIndex[c.source][c.target][c.id]=c,c.target!==c.source&&(this.allNeighborsIndex[c.target][c.source]||(this.allNeighborsIndex[c.target][c.source]=Object.create(null)),this.allNeighborsIndex[c.target][c.source][c.id]=c),this.inNeighborsCount[c.target]++,this.outNeighborsCount[c.source]++,this.allNeighborsCount[c.target]++,this.allNeighborsCount[c.source]++,this}),j.addMethod("dropNode",function(a){if("string"!=typeof a&&"number"!=typeof a||1!==arguments.length)throw"dropNode: Wrong arguments.";if(!this.nodesIndex[a])throw'The node "'+a+'" does not exist.';var b,c,d;for(delete this.nodesIndex[a],b=0,d=this.nodesArray.length;d>b;b++)if(this.nodesArray[b].id===a){this.nodesArray.splice(b,1);break}for(b=this.edgesArray.length-1;b>=0;b--)(this.edgesArray[b].source===a||this.edgesArray[b].target===a)&&this.dropEdge(this.edgesArray[b].id);delete this.inNeighborsIndex[a],delete this.outNeighborsIndex[a],delete this.allNeighborsIndex[a],delete this.inNeighborsCount[a],delete this.outNeighborsCount[a],delete this.allNeighborsCount[a];for(c in this.nodesIndex)delete this.inNeighborsIndex[c][a],delete this.outNeighborsIndex[c][a],delete this.allNeighborsIndex[c][a];return this}),j.addMethod("dropEdge",function(a){if("string"!=typeof a&&"number"!=typeof a||1!==arguments.length)throw"dropEdge: Wrong arguments.";if(!this.edgesIndex[a])throw'The edge "'+a+'" does not exist.';var b,c,d;for(d=this.edgesIndex[a],delete this.edgesIndex[a],b=0,c=this.edgesArray.length;c>b;b++)if(this.edgesArray[b].id===a){this.edgesArray.splice(b,1);break}return delete this.inNeighborsIndex[d.target][d.source][d.id],Object.keys(this.inNeighborsIndex[d.target][d.source]).length||delete this.inNeighborsIndex[d.target][d.source],delete this.outNeighborsIndex[d.source][d.target][d.id],Object.keys(this.outNeighborsIndex[d.source][d.target]).length||delete this.outNeighborsIndex[d.source][d.target],delete this.allNeighborsIndex[d.source][d.target][d.id],Object.keys(this.allNeighborsIndex[d.source][d.target]).length||delete this.allNeighborsIndex[d.source][d.target],d.target!==d.source&&(delete this.allNeighborsIndex[d.target][d.source][d.id],Object.keys(this.allNeighborsIndex[d.target][d.source]).length||delete this.allNeighborsIndex[d.target][d.source]),this.inNeighborsCount[d.target]--,this.outNeighborsCount[d.source]--,this.allNeighborsCount[d.source]--,this.allNeighborsCount[d.target]--,this}),j.addMethod("kill",function(){this.nodesArray.length=0,this.edgesArray.length=0,delete this.nodesArray,delete this.edgesArray,delete this.nodesIndex,delete this.edgesIndex,delete this.inNeighborsIndex,delete this.outNeighborsIndex,delete this.allNeighborsIndex,delete this.inNeighborsCount,delete this.outNeighborsCount,delete this.allNeighborsCount
+}),j.addMethod("clear",function(){return this.nodesArray.length=0,this.edgesArray.length=0,b(this.nodesIndex),b(this.edgesIndex),b(this.nodesIndex),b(this.inNeighborsIndex),b(this.outNeighborsIndex),b(this.allNeighborsIndex),b(this.inNeighborsCount),b(this.outNeighborsCount),b(this.allNeighborsCount),this}),j.addMethod("read",function(a){var b,c,d;for(c=a.nodes||[],b=0,d=c.length;d>b;b++)this.addNode(c[b]);for(c=a.edges||[],b=0,d=c.length;d>b;b++)this.addEdge(c[b]);return this}),j.addMethod("nodes",function(a){if(!arguments.length)return this.nodesArray.slice(0);if(1===arguments.length&&("string"==typeof a||"number"==typeof a))return this.nodesIndex[a];if(1===arguments.length&&"[object Array]"===Object.prototype.toString.call(a)){var b,c,d=[];for(b=0,c=a.length;c>b;b++){if("string"!=typeof a[b]&&"number"!=typeof a[b])throw"nodes: Wrong arguments.";d.push(this.nodesIndex[a[b]])}return d}throw"nodes: Wrong arguments."}),j.addMethod("degree",function(a,b){if(b={"in":this.inNeighborsCount,out:this.outNeighborsCount}[b||""]||this.allNeighborsCount,"string"==typeof a||"number"==typeof a)return b[a];if("[object Array]"===Object.prototype.toString.call(a)){var c,d,e=[];for(c=0,d=a.length;d>c;c++){if("string"!=typeof a[c]&&"number"!=typeof a[c])throw"degree: Wrong arguments.";e.push(b[a[c]])}return e}throw"degree: Wrong arguments."}),j.addMethod("edges",function(a){if(!arguments.length)return this.edgesArray.slice(0);if(1===arguments.length&&("string"==typeof a||"number"==typeof a))return this.edgesIndex[a];if(1===arguments.length&&"[object Array]"===Object.prototype.toString.call(a)){var b,c,d=[];for(b=0,c=a.length;c>b;b++){if("string"!=typeof a[b]&&"number"!=typeof a[b])throw"edges: Wrong arguments.";d.push(this.edgesIndex[a[b]])}return d}throw"edges: Wrong arguments."}),"undefined"!=typeof sigma?(sigma.classes=sigma.classes||Object.create(null),sigma.classes.graph=j):"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports.graph=j):this.graph=j}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.classes"),sigma.classes.camera=function(a,b,c,d){sigma.classes.dispatcher.extend(this),Object.defineProperty(this,"graph",{value:b}),Object.defineProperty(this,"id",{value:a}),Object.defineProperty(this,"readPrefix",{value:"read_cam"+a+":"}),Object.defineProperty(this,"prefix",{value:"cam"+a+":"}),this.x=0,this.y=0,this.ratio=1,this.angle=0,this.isAnimated=!1,this.settings="object"==typeof d&&d?c.embedObject(d):c},sigma.classes.camera.prototype.goTo=function(b){if(!this.settings("enableCamera"))return this;var c,d,e=b||{},f=["x","y","ratio","angle"];for(c=0,d=f.length;d>c;c++)if(e[f[c]]!==a){if("number"!=typeof e[f[c]]||isNaN(e[f[c]]))throw'Value for "'+f[c]+'" is not a number.';this[f[c]]=e[f[c]]}return this.dispatchEvent("coordinatesUpdated"),this},sigma.classes.camera.prototype.applyView=function(b,c,d){d=d||{},c=c!==a?c:this.prefix,b=b!==a?b:this.readPrefix;var e,f,g,h=d.nodes||this.graph.nodes(),i=d.edges||this.graph.edges(),j=Math.cos(this.angle),k=Math.sin(this.angle),l=Math.pow(this.ratio,this.settings("nodesPowRatio")),m=Math.pow(this.ratio,this.settings("edgesPowRatio")),n=(d.width||0)/2,o=(d.height||0)/2;for(e=0,f=h.length;f>e;e++)g=h[e],g[c+"x"]=(((g[b+"x"]||0)-this.x)*j+((g[b+"y"]||0)-this.y)*k)/this.ratio+n,g[c+"y"]=(((g[b+"y"]||0)-this.y)*j-((g[b+"x"]||0)-this.x)*k)/this.ratio+o,g[c+"size"]=(g[b+"size"]||0)/l;for(e=0,f=i.length;f>e;e++)i[e][c+"size"]=(i[e][b+"size"]||0)/m;return this},sigma.classes.camera.prototype.graphPosition=function(a,b,c){var d=0,e=0,f=Math.cos(this.angle),g=Math.sin(this.angle);return c||(d=-(this.x*f+this.y*g)/this.ratio,e=-(this.y*f-this.x*g)/this.ratio),{x:(a*f+b*g)/this.ratio+d,y:(b*f-a*g)/this.ratio+e}},sigma.classes.camera.prototype.cameraPosition=function(a,b,c){var d=0,e=0,f=Math.cos(this.angle),g=Math.sin(this.angle);return c||(d=-(this.x*f+this.y*g)/this.ratio,e=-(this.y*f-this.x*g)/this.ratio),{x:((a-d)*f-(b-e)*g)*this.ratio,y:((b-e)*f+(a-d)*g)*this.ratio}},sigma.classes.camera.prototype.getMatrix=function(){var a=sigma.utils.matrices.scale(1/this.ratio),b=sigma.utils.matrices.rotation(this.angle),c=sigma.utils.matrices.translation(-this.x,-this.y),d=sigma.utils.matrices.multiply(c,sigma.utils.matrices.multiply(b,a));return d},sigma.classes.camera.prototype.getRectangle=function(a,b){var c=this.cameraPosition(a,0,!0),d=this.cameraPosition(0,b,!0),e=this.cameraPosition(a/2,b/2,!0),f=this.cameraPosition(a/4,0,!0).x,g=this.cameraPosition(0,b/4,!0).y;return{x1:this.x-e.x-f,y1:this.y-e.y-g,x2:this.x-e.x+f+c.x,y2:this.y-e.y-g+c.y,height:Math.sqrt(Math.pow(d.x,2)+Math.pow(d.y+2*g,2))}}}.call(this),function(a){"use strict";function b(a,b){var c=b.x+b.width/2,d=b.y+b.height/2,e=a.y<d,f=a.x<c;return e?f?0:1:f?2:3}function c(a,b){for(var c=[],d=0;4>d;d++)a.x2>=b[d][0].x&&a.x1<=b[d][1].x&&a.y1+a.height>=b[d][0].y&&a.y1<=b[d][2].y&&c.push(d);return c}function d(a,b){for(var c=[],d=0;4>d;d++)j.collision(a,b[d])&&c.push(d);return c}function e(a,b){var c,d,e=b.level+1,f=Math.round(b.bounds.width/2),g=Math.round(b.bounds.height/2),h=Math.round(b.bounds.x),j=Math.round(b.bounds.y);switch(a){case 0:c=h,d=j;break;case 1:c=h+f,d=j;break;case 2:c=h,d=j+g;break;case 3:c=h+f,d=j+g}return i({x:c,y:d,width:f,height:g},e,b.maxElements,b.maxLevel)}function f(b,d,g){if(g.level<g.maxLevel)for(var h=c(d,g.corners),i=0,j=h.length;j>i;i++)g.nodes[h[i]]===a&&(g.nodes[h[i]]=e(h[i],g)),f(b,d,g.nodes[h[i]]);else g.elements.push(b)}function g(c,d){if(d.level<d.maxLevel){var e=b(c,d.bounds);return d.nodes[e]!==a?g(c,d.nodes[e]):[]}return d.elements}function h(b,c,d,e){if(e=e||{},c.level<c.maxLevel)for(var f=d(b,c.corners),g=0,i=f.length;i>g;g++)c.nodes[f[g]]!==a&&h(b,c.nodes[f[g]],d,e);else for(var j=0,k=c.elements.length;k>j;j++)e[c.elements[j].id]===a&&(e[c.elements[j].id]=c.elements[j]);return e}function i(a,b,c,d){return{level:b||0,bounds:a,corners:j.splitSquare(a),maxElements:c||20,maxLevel:d||4,elements:[],nodes:[]}}var j={pointToSquare:function(a){return{x1:a.x-a.size,y1:a.y-a.size,x2:a.x+a.size,y2:a.y-a.size,height:2*a.size}},isAxisAligned:function(a){return a.x1===a.x2||a.y1===a.y2},axisAlignedTopPoints:function(a){return a.y1===a.y2&&a.x1<a.x2?a:a.x1===a.x2&&a.y2>a.y1?{x1:a.x1-a.height,y1:a.y1,x2:a.x1,y2:a.y1,height:a.height}:a.x1===a.x2&&a.y2<a.y1?{x1:a.x1,y1:a.y2,x2:a.x2+a.height,y2:a.y2,height:a.height}:{x1:a.x2,y1:a.y1-a.height,x2:a.x1,y2:a.y1-a.height,height:a.height}},lowerLeftCoor:function(a){var b=Math.sqrt(Math.pow(a.x2-a.x1,2)+Math.pow(a.y2-a.y1,2));return{x:a.x1-(a.y2-a.y1)*a.height/b,y:a.y1+(a.x2-a.x1)*a.height/b}},lowerRightCoor:function(a,b){return{x:b.x-a.x1+a.x2,y:b.y-a.y1+a.y2}},rectangleCorners:function(a){var b=this.lowerLeftCoor(a),c=this.lowerRightCoor(a,b);return[{x:a.x1,y:a.y1},{x:a.x2,y:a.y2},{x:b.x,y:b.y},{x:c.x,y:c.y}]},splitSquare:function(a){return[[{x:a.x,y:a.y},{x:a.x+a.width/2,y:a.y},{x:a.x,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height/2}],[{x:a.x+a.width/2,y:a.y},{x:a.x+a.width,y:a.y},{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x+a.width,y:a.y+a.height/2}],[{x:a.x,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x,y:a.y+a.height},{x:a.x+a.width/2,y:a.y+a.height}],[{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x+a.width,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height},{x:a.x+a.width,y:a.y+a.height}]]},axis:function(a,b){return[{x:a[1].x-a[0].x,y:a[1].y-a[0].y},{x:a[1].x-a[3].x,y:a[1].y-a[3].y},{x:b[0].x-b[2].x,y:b[0].y-b[2].y},{x:b[0].x-b[1].x,y:b[0].y-b[1].y}]},projection:function(a,b){var c=(a.x*b.x+a.y*b.y)/(Math.pow(b.x,2)+Math.pow(b.y,2));return{x:c*b.x,y:c*b.y}},axisCollision:function(a,b,c){for(var d=[],e=[],f=0;4>f;f++){var g=this.projection(b[f],a),h=this.projection(c[f],a);d.push(g.x*a.x+g.y*a.y),e.push(h.x*a.x+h.y*a.y)}var i=Math.max.apply(Math,d),j=Math.max.apply(Math,e),k=Math.min.apply(Math,d),l=Math.min.apply(Math,e);return i>=l&&j>=k},collision:function(a,b){for(var c=this.axis(a,b),d=!0,e=0;4>e;e++)d=d&&this.axisCollision(c[e],a,b);return d}},k=function(){this._geom=j,this._tree=null,this._cache={query:!1,result:!1}};k.prototype.index=function(a,b){if(!b.bounds)throw"sigma.classes.quad.index: bounds information not given.";var c=b.prefix||"";this._tree=i(b.bounds,0,b.maxElements,b.maxLevel);for(var d=0,e=a.length;e>d;d++)f(a[d],j.pointToSquare({x:a[d][c+"x"],y:a[d][c+"y"],size:a[d][c+"size"]}),this._tree);return this._cache={query:!1,result:!1},this._tree},k.prototype.point=function(a,b){return this._tree?g({x:a,y:b},this._tree)||[]:[]},k.prototype.area=function(a){var b,e,f=JSON.stringify(a);if(this._cache.query===f)return this._cache.result;j.isAxisAligned(a)?(b=c,e=j.axisAlignedTopPoints(a)):(b=d,e=j.rectangleCorners(a));var g=this._tree?h(e,this._tree,b):[],i=[];for(var k in g)i.push(g[k]);return this._cache.query=f,this._cache.result=i,i},"undefined"!=typeof this.sigma?(this.sigma.classes=this.sigma.classes||{},this.sigma.classes.quad=k):"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=k),exports.quad=k):this.quad=k}.call(this),function(a){"use strict";function b(a,b){var c=b.x+b.width/2,d=b.y+b.height/2,e=a.y<d,f=a.x<c;return e?f?0:1:f?2:3}function c(a,b){for(var c=[],d=0;4>d;d++)a.x2>=b[d][0].x&&a.x1<=b[d][1].x&&a.y1+a.height>=b[d][0].y&&a.y1<=b[d][2].y&&c.push(d);return c}function d(a,b){for(var c=[],d=0;4>d;d++)j.collision(a,b[d])&&c.push(d);return c}function e(a,b){var c,d,e=b.level+1,f=Math.round(b.bounds.width/2),g=Math.round(b.bounds.height/2),h=Math.round(b.bounds.x),j=Math.round(b.bounds.y);switch(a){case 0:c=h,d=j;break;case 1:c=h+f,d=j;break;case 2:c=h,d=j+g;break;case 3:c=h+f,d=j+g}return i({x:c,y:d,width:f,height:g},e,b.maxElements,b.maxLevel)}function f(b,d,g){if(g.level<g.maxLevel)for(var h=c(d,g.corners),i=0,j=h.length;j>i;i++)g.nodes[h[i]]===a&&(g.nodes[h[i]]=e(h[i],g)),f(b,d,g.nodes[h[i]]);else g.elements.push(b)}function g(c,d){if(d.level<d.maxLevel){var e=b(c,d.bounds);return d.nodes[e]!==a?g(c,d.nodes[e]):[]}return d.elements}function h(b,c,d,e){if(e=e||{},c.level<c.maxLevel)for(var f=d(b,c.corners),g=0,i=f.length;i>g;g++)c.nodes[f[g]]!==a&&h(b,c.nodes[f[g]],d,e);else for(var j=0,k=c.elements.length;k>j;j++)e[c.elements[j].id]===a&&(e[c.elements[j].id]=c.elements[j]);return e}function i(a,b,c,d){return{level:b||0,bounds:a,corners:j.splitSquare(a),maxElements:c||40,maxLevel:d||8,elements:[],nodes:[]}}var j={pointToSquare:function(a){return{x1:a.x-a.size,y1:a.y-a.size,x2:a.x+a.size,y2:a.y-a.size,height:2*a.size}},lineToSquare:function(a){return a.y1<a.y2?a.x1<a.x2?{x1:a.x1-a.size,y1:a.y1-a.size,x2:a.x2+a.size,y2:a.y1-a.size,height:a.y2-a.y1+2*a.size}:{x1:a.x2-a.size,y1:a.y1-a.size,x2:a.x1+a.size,y2:a.y1-a.size,height:a.y2-a.y1+2*a.size}:a.x1<a.x2?{x1:a.x1-a.size,y1:a.y2-a.size,x2:a.x2+a.size,y2:a.y2-a.size,height:a.y1-a.y2+2*a.size}:{x1:a.x2-a.size,y1:a.y2-a.size,x2:a.x1+a.size,y2:a.y2-a.size,height:a.y1-a.y2+2*a.size}},quadraticCurveToSquare:function(a,b){var c=sigma.utils.getPointOnQuadraticCurve(.5,a.x1,a.y1,a.x2,a.y2,b.x,b.y),d=Math.min(a.x1,a.x2,c.x),e=Math.max(a.x1,a.x2,c.x),f=Math.min(a.y1,a.y2,c.y),g=Math.max(a.y1,a.y2,c.y);return{x1:d-a.size,y1:f-a.size,x2:e+a.size,y2:f-a.size,height:g-f+2*a.size}},selfLoopToSquare:function(a){var b=sigma.utils.getSelfLoopControlPoints(a.x,a.y,a.size),c=Math.min(a.x,b.x1,b.x2),d=Math.max(a.x,b.x1,b.x2),e=Math.min(a.y,b.y1,b.y2),f=Math.max(a.y,b.y1,b.y2);return{x1:c-a.size,y1:e-a.size,x2:d+a.size,y2:e-a.size,height:f-e+2*a.size}},isAxisAligned:function(a){return a.x1===a.x2||a.y1===a.y2},axisAlignedTopPoints:function(a){return a.y1===a.y2&&a.x1<a.x2?a:a.x1===a.x2&&a.y2>a.y1?{x1:a.x1-a.height,y1:a.y1,x2:a.x1,y2:a.y1,height:a.height}:a.x1===a.x2&&a.y2<a.y1?{x1:a.x1,y1:a.y2,x2:a.x2+a.height,y2:a.y2,height:a.height}:{x1:a.x2,y1:a.y1-a.height,x2:a.x1,y2:a.y1-a.height,height:a.height}},lowerLeftCoor:function(a){var b=Math.sqrt(Math.pow(a.x2-a.x1,2)+Math.pow(a.y2-a.y1,2));return{x:a.x1-(a.y2-a.y1)*a.height/b,y:a.y1+(a.x2-a.x1)*a.height/b}},lowerRightCoor:function(a,b){return{x:b.x-a.x1+a.x2,y:b.y-a.y1+a.y2}},rectangleCorners:function(a){var b=this.lowerLeftCoor(a),c=this.lowerRightCoor(a,b);return[{x:a.x1,y:a.y1},{x:a.x2,y:a.y2},{x:b.x,y:b.y},{x:c.x,y:c.y}]},splitSquare:function(a){return[[{x:a.x,y:a.y},{x:a.x+a.width/2,y:a.y},{x:a.x,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height/2}],[{x:a.x+a.width/2,y:a.y},{x:a.x+a.width,y:a.y},{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x+a.width,y:a.y+a.height/2}],[{x:a.x,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x,y:a.y+a.height},{x:a.x+a.width/2,y:a.y+a.height}],[{x:a.x+a.width/2,y:a.y+a.height/2},{x:a.x+a.width,y:a.y+a.height/2},{x:a.x+a.width/2,y:a.y+a.height},{x:a.x+a.width,y:a.y+a.height}]]},axis:function(a,b){return[{x:a[1].x-a[0].x,y:a[1].y-a[0].y},{x:a[1].x-a[3].x,y:a[1].y-a[3].y},{x:b[0].x-b[2].x,y:b[0].y-b[2].y},{x:b[0].x-b[1].x,y:b[0].y-b[1].y}]},projection:function(a,b){var c=(a.x*b.x+a.y*b.y)/(Math.pow(b.x,2)+Math.pow(b.y,2));return{x:c*b.x,y:c*b.y}},axisCollision:function(a,b,c){for(var d=[],e=[],f=0;4>f;f++){var g=this.projection(b[f],a),h=this.projection(c[f],a);d.push(g.x*a.x+g.y*a.y),e.push(h.x*a.x+h.y*a.y)}var i=Math.max.apply(Math,d),j=Math.max.apply(Math,e),k=Math.min.apply(Math,d),l=Math.min.apply(Math,e);return i>=l&&j>=k},collision:function(a,b){for(var c=this.axis(a,b),d=!0,e=0;4>e;e++)d=d&&this.axisCollision(c[e],a,b);return d}},k=function(){this._geom=j,this._tree=null,this._cache={query:!1,result:!1},this._enabled=!0};k.prototype.index=function(a,b){if(!this._enabled)return this._tree;if(!b.bounds)throw"sigma.classes.edgequad.index: bounds information not given.";var c,d,e,g,h,k=b.prefix||"";this._tree=i(b.bounds,0,b.maxElements,b.maxLevel);for(var l=a.edges(),m=0,n=l.length;n>m;m++)d=a.nodes(l[m].source),e=a.nodes(l[m].target),h={x1:d[k+"x"],y1:d[k+"y"],x2:e[k+"x"],y2:e[k+"y"],size:l[m][k+"size"]||0},"curve"===l[m].type||"curvedArrow"===l[m].type?d.id===e.id?(g={x:d[k+"x"],y:d[k+"y"],size:d[k+"size"]||0},f(l[m],j.selfLoopToSquare(g),this._tree)):(c=sigma.utils.getQuadraticControlPoint(h.x1,h.y1,h.x2,h.y2),f(l[m],j.quadraticCurveToSquare(h,c),this._tree)):f(l[m],j.lineToSquare(h),this._tree);return this._cache={query:!1,result:!1},this._tree},k.prototype.point=function(a,b){return this._enabled&&this._tree?g({x:a,y:b},this._tree)||[]:[]},k.prototype.area=function(a){if(!this._enabled)return[];var b,e,f=JSON.stringify(a);if(this._cache.query===f)return this._cache.result;j.isAxisAligned(a)?(b=c,e=j.axisAlignedTopPoints(a)):(b=d,e=j.rectangleCorners(a));var g=this._tree?h(e,this._tree,b):[],i=[];for(var k in g)i.push(g[k]);return this._cache.query=f,this._cache.result=i,i},"undefined"!=typeof this.sigma?(this.sigma.classes=this.sigma.classes||{},this.sigma.classes.edgequad=k):"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=k),exports.edgequad=k):this.edgequad=k}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.captors"),sigma.captors.mouse=function(a,b,c){function d(a){var b,c,d;return y("mouseEnabled")&&(v.dispatchEvent("mousemove",sigma.utils.mouseCoords(a)),q)?(r=!0,s=!0,u&&clearTimeout(u),u=setTimeout(function(){r=!1},y("dragTimeout")),sigma.misc.animation.killAll(x),x.isMoving=!0,d=x.cameraPosition(sigma.utils.getX(a)-o,sigma.utils.getY(a)-p,!0),b=k-d.x,c=l-d.y,(b!==x.x||c!==x.y)&&(m=x.x,n=x.y,x.goTo({x:b,y:c})),a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation(),!1):void 0}function e(a){if(y("mouseEnabled")&&q){q=!1,u&&clearTimeout(u),x.isMoving=!1;var b=sigma.utils.getX(a),c=sigma.utils.getY(a);r?(sigma.misc.animation.killAll(x),sigma.misc.animation.camera(x,{x:x.x+y("mouseInertiaRatio")*(x.x-m),y:x.y+y("mouseInertiaRatio")*(x.y-n)},{easing:"quadraticOut",duration:y("mouseInertiaDuration")})):(o!==b||p!==c)&&x.goTo({x:x.x,y:x.y}),v.dispatchEvent("mouseup",sigma.utils.mouseCoords(a)),r=!1}}function f(a){if(y("mouseEnabled"))switch(k=x.x,l=x.y,m=x.x,n=x.y,o=sigma.utils.getX(a),p=sigma.utils.getY(a),s=!1,t=(new Date).getTime(),a.which){case 2:break;case 3:v.dispatchEvent("rightclick",sigma.utils.mouseCoords(a,o,p));break;default:q=!0,v.dispatchEvent("mousedown",sigma.utils.mouseCoords(a,o,p))}}function g(){y("mouseEnabled")&&v.dispatchEvent("mouseout")}function h(a){if(y("mouseEnabled")){var b=sigma.utils.mouseCoords(a);b.isDragging=(new Date).getTime()-t>100&&s,v.dispatchEvent("click",b)}return a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation(),!1}function i(a){var b,c,d;return y("mouseEnabled")?(c=1/y("doubleClickZoomingRatio"),v.dispatchEvent("doubleclick",sigma.utils.mouseCoords(a,o,p)),y("doubleClickEnabled")&&(b=x.cameraPosition(sigma.utils.getX(a)-sigma.utils.getCenter(a).x,sigma.utils.getY(a)-sigma.utils.getCenter(a).y,!0),d={duration:y("doubleClickZoomDuration")},sigma.utils.zoomTo(x,b.x,b.y,c,d)),a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation(),!1):void 0}function j(a){var b,c,d;return y("mouseEnabled")&&y("mouseWheelEnabled")?(c=sigma.utils.getDelta(a)>0?1/y("zoomingRatio"):y("zoomingRatio"),b=x.cameraPosition(sigma.utils.getX(a)-sigma.utils.getCenter(a).x,sigma.utils.getY(a)-sigma.utils.getCenter(a).y,!0),d={duration:y("mouseZoomDuration")},sigma.utils.zoomTo(x,b.x,b.y,c,d),a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation(),!1):void 0}var k,l,m,n,o,p,q,r,s,t,u,v=this,w=a,x=b,y=c;sigma.classes.dispatcher.extend(this),sigma.utils.doubleClick(w,"click",i),w.addEventListener("DOMMouseScroll",j,!1),w.addEventListener("mousewheel",j,!1),w.addEventListener("mousemove",d,!1),w.addEventListener("mousedown",f,!1),w.addEventListener("click",h,!1),w.addEventListener("mouseout",g,!1),document.addEventListener("mouseup",e,!1),this.kill=function(){sigma.utils.unbindDoubleClick(w,"click"),w.removeEventListener("DOMMouseScroll",j),w.removeEventListener("mousewheel",j),w.removeEventListener("mousemove",d),w.removeEventListener("mousedown",f),w.removeEventListener("click",h),w.removeEventListener("mouseout",g),document.removeEventListener("mouseup",e)}}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.captors"),sigma.captors.touch=function(a,b,c){function d(a){var b=sigma.utils.getOffset(B);return{x:a.pageX-b.left,y:a.pageY-b.top}}function e(a){if(D("touchEnabled")){var b,c,e,f,g,h;switch(E=a.touches,E.length){case 1:C.isMoving=!0,w=1,i=C.x,j=C.y,m=C.x,n=C.y,g=d(E[0]),q=g.x,r=g.y;break;case 2:return C.isMoving=!0,w=2,g=d(E[0]),h=d(E[1]),b=g.x,e=g.y,c=h.x,f=h.y,m=C.x,n=C.y,k=C.angle,l=C.ratio,i=C.x,j=C.y,q=b,r=e,s=c,t=f,u=Math.atan2(t-r,s-q),v=Math.sqrt((t-r)*(t-r)+(s-q)*(s-q)),a.preventDefault(),!1}}}function f(a){if(D("touchEnabled")){E=a.touches;var b=D("touchInertiaRatio");switch(z&&(x=!1,clearTimeout(z)),w){case 2:if(1===a.touches.length){e(a),a.preventDefault();break}case 1:C.isMoving=!1,A.dispatchEvent("stopDrag"),x&&(y=!1,sigma.misc.animation.camera(C,{x:C.x+b*(C.x-m),y:C.y+b*(C.y-n)},{easing:"quadraticOut",duration:D("touchInertiaDuration")})),x=!1,w=0}}}function g(a){if(!y&&D("touchEnabled")){var b,c,e,f,g,h,B,F,G,H,I,J,K,L,M,N,O;switch(E=a.touches,x=!0,z&&clearTimeout(z),z=setTimeout(function(){x=!1},D("dragTimeout")),w){case 1:F=d(E[0]),b=F.x,e=F.y,H=C.cameraPosition(b-q,e-r,!0),L=i-H.x,M=j-H.y,(L!==C.x||M!==C.y)&&(m=C.x,n=C.y,C.goTo({x:L,y:M}),A.dispatchEvent("mousemove",sigma.utils.mouseCoords(a,F.x,F.y)),A.dispatchEvent("drag"));break;case 2:F=d(E[0]),G=d(E[1]),b=F.x,e=F.y,c=G.x,f=G.y,I=C.cameraPosition((q+s)/2-sigma.utils.getCenter(a).x,(r+t)/2-sigma.utils.getCenter(a).y,!0),B=C.cameraPosition((b+c)/2-sigma.utils.getCenter(a).x,(e+f)/2-sigma.utils.getCenter(a).y,!0),J=Math.atan2(f-e,c-b)-u,K=Math.sqrt((f-e)*(f-e)+(c-b)*(c-b))/v,b=I.x,e=I.y,N=l/K,b*=K,e*=K,O=k-J,g=Math.cos(-J),h=Math.sin(-J),c=b*g+e*h,f=e*g-b*h,b=c,e=f,L=b-B.x+i,M=e-B.y+j,(N!==C.ratio||O!==C.angle||L!==C.x||M!==C.y)&&(m=C.x,n=C.y,o=C.angle,p=C.ratio,C.goTo({x:L,y:M,angle:O,ratio:N}),A.dispatchEvent("drag"))}return a.preventDefault(),!1}}function h(a){var b,c,e;return a.touches&&1===a.touches.length&&D("touchEnabled")?(y=!0,c=1/D("doubleClickZoomingRatio"),b=d(a.touches[0]),A.dispatchEvent("doubleclick",sigma.utils.mouseCoords(a,b.x,b.y)),D("doubleClickEnabled")&&(b=C.cameraPosition(b.x-sigma.utils.getCenter(a).x,b.y-sigma.utils.getCenter(a).y,!0),e={duration:D("doubleClickZoomDuration"),onComplete:function(){y=!1}},sigma.utils.zoomTo(C,b.x,b.y,c,e)),a.preventDefault?a.preventDefault():a.returnValue=!1,a.stopPropagation(),!1):void 0}var i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A=this,B=a,C=b,D=c,E=[];sigma.classes.dispatcher.extend(this),sigma.utils.doubleClick(B,"touchstart",h),B.addEventListener("touchstart",e,!1),B.addEventListener("touchend",f,!1),B.addEventListener("touchcancel",f,!1),B.addEventListener("touchleave",f,!1),B.addEventListener("touchmove",g,!1),this.kill=function(){sigma.utils.unbindDoubleClick(B,"touchstart"),B.addEventListener("touchstart",e),B.addEventListener("touchend",f),B.addEventListener("touchcancel",f),B.addEventListener("touchleave",f),B.addEventListener("touchmove",g)}}}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";if("undefined"==typeof conrad)throw"conrad is not declared";sigma.utils.pkg("sigma.renderers"),sigma.renderers.canvas=function(a,b,c,d){if("object"!=typeof d)throw"sigma.renderers.canvas: Wrong arguments.";if(!(d.container instanceof HTMLElement))throw"Container not found.";var e,f,g,h;for(sigma.classes.dispatcher.extend(this),Object.defineProperty(this,"conradId",{value:sigma.utils.id()}),this.graph=a,this.camera=b,this.contexts={},this.domElements={},this.options=d,this.container=this.options.container,this.settings="object"==typeof d.settings&&d.settings?c.embedObjects(d.settings):c,this.nodesOnScreen=[],this.edgesOnScreen=[],this.jobs={},this.options.prefix="renderer"+this.conradId+":",this.settings("batchEdgesDrawing")?(this.initDOM("canvas","edges"),this.initDOM("canvas","scene"),this.contexts.nodes=this.contexts.scene,this.contexts.labels=this.contexts.scene):(this.initDOM("canvas","scene"),this.contexts.edges=this.contexts.scene,this.contexts.nodes=this.contexts.scene,this.contexts.labels=this.contexts.scene),this.initDOM("canvas","mouse"),this.contexts.hover=this.contexts.mouse,this.captors=[],g=this.options.captors||[sigma.captors.mouse,sigma.captors.touch],e=0,f=g.length;f>e;e++)h="function"==typeof g[e]?g[e]:sigma.captors[g[e]],this.captors.push(new h(this.domElements.mouse,this.camera,this.settings));sigma.misc.bindEvents.call(this,this.options.prefix),sigma.misc.drawHovers.call(this,this.options.prefix),this.resize(!1)},sigma.renderers.canvas.prototype.render=function(b){b=b||{};var c,d,e,f,g,h,i,j,k,l,m,n,o,p={},q=this.graph,r=this.graph.nodes,s=(this.options.prefix||"",this.settings(b,"drawEdges")),t=this.settings(b,"drawNodes"),u=this.settings(b,"drawLabels"),v=this.settings(b,"drawEdgeLabels"),w=this.settings.embedObjects(b,{prefix:this.options.prefix});this.resize(!1),this.settings(b,"hideEdgesOnMove")&&(this.camera.isAnimated||this.camera.isMoving)&&(s=!1),this.camera.applyView(a,this.options.prefix,{width:this.width,height:this.height}),this.clear();for(e in this.jobs)conrad.hasJob(e)&&conrad.killJob(e);for(this.edgesOnScreen=[],this.nodesOnScreen=this.camera.quadtree.area(this.camera.getRectangle(this.width,this.height)),c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)p[c[d].id]=c[d];if(s){for(c=q.edges(),d=0,f=c.length;f>d;d++)g=c[d],!p[g.source]&&!p[g.target]||g.hidden||r(g.source).hidden||r(g.target).hidden||this.edgesOnScreen.push(g);if(this.settings(b,"batchEdgesDrawing"))h="edges_"+this.conradId,n=w("canvasEdgesBatchSize"),l=this.edgesOnScreen,f=l.length,k=0,i=Math.min(l.length,k+n),j=function(){for(o=this.contexts.edges.globalCompositeOperation,this.contexts.edges.globalCompositeOperation="destination-over",m=sigma.canvas.edges,d=k;i>d;d++)g=l[d],(m[g.type||this.settings(b,"defaultEdgeType")]||m.def)(g,q.nodes(g.source),q.nodes(g.target),this.contexts.edges,w);if(v)for(m=sigma.canvas.edges.labels,d=k;i>d;d++)g=l[d],g.hidden||(m[g.type||this.settings(b,"defaultEdgeType")]||m.def)(g,q.nodes(g.source),q.nodes(g.target),this.contexts.labels,w);return this.contexts.edges.globalCompositeOperation=o,i===l.length?(delete this.jobs[h],!1):(k=i+1,i=Math.min(l.length,k+n),!0)},this.jobs[h]=j,conrad.addJob(h,j.bind(this));else{for(m=sigma.canvas.edges,c=this.edgesOnScreen,d=0,f=c.length;f>d;d++)g=c[d],(m[g.type||this.settings(b,"defaultEdgeType")]||m.def)(g,q.nodes(g.source),q.nodes(g.target),this.contexts.edges,w);if(v)for(m=sigma.canvas.edges.labels,c=this.edgesOnScreen,d=0,f=c.length;f>d;d++)c[d].hidden||(m[c[d].type||this.settings(b,"defaultEdgeType")]||m.def)(c[d],q.nodes(c[d].source),q.nodes(c[d].target),this.contexts.labels,w)}}if(t)for(m=sigma.canvas.nodes,c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)c[d].hidden||(m[c[d].type||this.settings(b,"defaultNodeType")]||m.def)(c[d],this.contexts.nodes,w);if(u)for(m=sigma.canvas.labels,c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)c[d].hidden||(m[c[d].type||this.settings(b,"defaultNodeType")]||m.def)(c[d],this.contexts.labels,w);return this.dispatchEvent("render"),this},sigma.renderers.canvas.prototype.initDOM=function(a,b){var c=document.createElement(a);c.style.position="absolute",c.setAttribute("class","sigma-"+b),this.domElements[b]=c,this.container.appendChild(c),"canvas"===a.toLowerCase()&&(this.contexts[b]=c.getContext("2d"))},sigma.renderers.canvas.prototype.resize=function(b,c){var d,e=this.width,f=this.height,g=sigma.utils.getPixelRatio();if(b!==a&&c!==a?(this.width=b,this.height=c):(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,b=this.width,c=this.height),e!==this.width||f!==this.height)for(d in this.domElements)this.domElements[d].style.width=b+"px",this.domElements[d].style.height=c+"px","canvas"===this.domElements[d].tagName.toLowerCase()&&(this.domElements[d].setAttribute("width",b*g+"px"),this.domElements[d].setAttribute("height",c*g+"px"),1!==g&&this.contexts[d].scale(g,g));return this},sigma.renderers.canvas.prototype.clear=function(){for(var a in this.contexts)this.contexts[a].clearRect(0,0,this.width,this.height);return this},sigma.renderers.canvas.prototype.kill=function(){for(var a,b;b=this.captors.pop();)b.kill();delete this.captors;for(a in this.domElements)this.domElements[a].parentNode.removeChild(this.domElements[a]),delete this.domElements[a],delete this.contexts[a];delete this.domElements,delete this.contexts},sigma.utils.pkg("sigma.canvas.nodes"),sigma.utils.pkg("sigma.canvas.edges"),sigma.utils.pkg("sigma.canvas.labels")}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.renderers"),sigma.renderers.webgl=function(a,b,c,d){if("object"!=typeof d)throw"sigma.renderers.webgl: Wrong arguments.";if(!(d.container instanceof HTMLElement))throw"Container not found.";var e,f,g,h;for(sigma.classes.dispatcher.extend(this),this.jobs={},Object.defineProperty(this,"conradId",{value:sigma.utils.id()}),this.graph=a,this.camera=b,this.contexts={},this.domElements={},this.options=d,this.container=this.options.container,this.settings="object"==typeof d.settings&&d.settings?c.embedObjects(d.settings):c,this.options.prefix=this.camera.readPrefix,Object.defineProperty(this,"nodePrograms",{value:{}}),Object.defineProperty(this,"edgePrograms",{value:{}}),Object.defineProperty(this,"nodeFloatArrays",{value:{}}),Object.defineProperty(this,"edgeFloatArrays",{value:{}}),Object.defineProperty(this,"edgeIndicesArrays",{value:{}}),this.settings(d,"batchEdgesDrawing")?(this.initDOM("canvas","edges",!0),this.initDOM("canvas","nodes",!0)):(this.initDOM("canvas","scene",!0),this.contexts.nodes=this.contexts.scene,this.contexts.edges=this.contexts.scene),this.initDOM("canvas","labels"),this.initDOM("canvas","mouse"),this.contexts.hover=this.contexts.mouse,this.captors=[],g=this.options.captors||[sigma.captors.mouse,sigma.captors.touch],e=0,f=g.length;f>e;e++)h="function"==typeof g[e]?g[e]:sigma.captors[g[e]],this.captors.push(new h(this.domElements.mouse,this.camera,this.settings));sigma.misc.bindEvents.call(this,this.camera.prefix),sigma.misc.drawHovers.call(this,this.camera.prefix),this.resize()},sigma.renderers.webgl.prototype.process=function(){var a,b,c,d,e,f,g=this.graph,h=sigma.utils.extend(h,this.options),i=this.settings(h,"defaultEdgeType"),j=this.settings(h,"defaultNodeType");for(d in this.nodeFloatArrays)delete this.nodeFloatArrays[d];for(d in this.edgeFloatArrays)delete this.edgeFloatArrays[d];for(d in this.edgeIndicesArrays)delete this.edgeIndicesArrays[d];for(a=g.edges(),b=0,c=a.length;c>b;b++)e=a[b].type||i,d=e&&sigma.webgl.edges[e]?e:"def",this.edgeFloatArrays[d]||(this.edgeFloatArrays[d]={edges:[]}),this.edgeFloatArrays[d].edges.push(a[b]);for(a=g.nodes(),b=0,c=a.length;c>b;b++)e=a[b].type||j,d=e&&sigma.webgl.nodes[e]?e:"def",this.nodeFloatArrays[d]||(this.nodeFloatArrays[d]={nodes:[]}),this.nodeFloatArrays[d].nodes.push(a[b]);for(d in this.edgeFloatArrays){for(f=sigma.webgl.edges[d],a=this.edgeFloatArrays[d].edges,this.edgeFloatArrays[d].array=new Float32Array(a.length*f.POINTS*f.ATTRIBUTES),b=0,c=a.length;c>b;b++)a[b].hidden||g.nodes(a[b].source).hidden||g.nodes(a[b].target).hidden||f.addEdge(a[b],g.nodes(a[b].source),g.nodes(a[b].target),this.edgeFloatArrays[d].array,b*f.POINTS*f.ATTRIBUTES,h.prefix,this.settings);"function"==typeof f.computeIndices&&(this.edgeIndicesArrays[d]=f.computeIndices(this.edgeFloatArrays[d].array))}for(d in this.nodeFloatArrays)for(f=sigma.webgl.nodes[d],a=this.nodeFloatArrays[d].nodes,this.nodeFloatArrays[d].array=new Float32Array(a.length*f.POINTS*f.ATTRIBUTES),b=0,c=a.length;c>b;b++)this.nodeFloatArrays[d].array||(this.nodeFloatArrays[d].array=new Float32Array(a.length*f.POINTS*f.ATTRIBUTES)),a[b].hidden||f.addNode(a[b],this.nodeFloatArrays[d].array,b*f.POINTS*f.ATTRIBUTES,h.prefix,this.settings);return this},sigma.renderers.webgl.prototype.render=function(b){var c,d,e,f,g,h,i=this,j=(this.graph,this.contexts.nodes),k=this.contexts.edges,l=this.camera.getMatrix(),m=sigma.utils.extend(b,this.options),n=this.settings(m,"drawLabels"),o=this.settings(m,"drawEdges"),p=this.settings(m,"drawNodes");this.resize(!1),this.settings(m,"hideEdgesOnMove")&&(this.camera.isAnimated||this.camera.isMoving)&&(o=!1),this.clear(),l=sigma.utils.matrices.multiply(l,sigma.utils.matrices.translation(this.width/2,this.height/2));for(f in this.jobs)conrad.hasJob(f)&&conrad.killJob(f);if(o)if(this.settings(m,"batchEdgesDrawing"))(function(){var a,b,c,d,e,f,g,h,i,j;c="edges_"+this.conradId,j=this.settings(m,"webglEdgesBatchSize"),a=Object.keys(this.edgeFloatArrays),a.length&&(b=0,i=sigma.webgl.edges[a[b]],e=this.edgeFloatArrays[a[b]].array,h=this.edgeIndicesArrays[a[b]],g=0,f=Math.min(g+j*i.POINTS,e.length/i.ATTRIBUTES),d=function(){return this.edgePrograms[a[b]]||(this.edgePrograms[a[b]]=i.initProgram(k)),f>g&&(k.useProgram(this.edgePrograms[a[b]]),i.render(k,this.edgePrograms[a[b]],e,{settings:this.settings,matrix:l,width:this.width,height:this.height,ratio:this.camera.ratio,scalingRatio:this.settings(m,"webglOversamplingRatio"),start:g,count:f-g,indicesData:h})),f>=e.length/i.ATTRIBUTES&&b===a.length-1?(delete this.jobs[c],!1):(f>=e.length/i.ATTRIBUTES?(b++,e=this.edgeFloatArrays[a[b]].array,i=sigma.webgl.edges[a[b]],g=0,f=Math.min(g+j*i.POINTS,e.length/i.ATTRIBUTES)):(g=f,f=Math.min(g+j*i.POINTS,e.length/i.ATTRIBUTES)),!0)},this.jobs[c]=d,conrad.addJob(c,d.bind(this)))}).call(this);else for(f in this.edgeFloatArrays)h=sigma.webgl.edges[f],this.edgePrograms[f]||(this.edgePrograms[f]=h.initProgram(k)),this.edgeFloatArrays[f]&&(k.useProgram(this.edgePrograms[f]),h.render(k,this.edgePrograms[f],this.edgeFloatArrays[f].array,{settings:this.settings,matrix:l,width:this.width,height:this.height,ratio:this.camera.ratio,scalingRatio:this.settings(m,"webglOversamplingRatio"),indicesData:this.edgeIndicesArrays[f]}));
+if(p){j.blendFunc(j.SRC_ALPHA,j.ONE_MINUS_SRC_ALPHA),j.enable(j.BLEND);for(f in this.nodeFloatArrays)h=sigma.webgl.nodes[f],this.nodePrograms[f]||(this.nodePrograms[f]=h.initProgram(j)),this.nodeFloatArrays[f]&&(j.useProgram(this.nodePrograms[f]),h.render(j,this.nodePrograms[f],this.nodeFloatArrays[f].array,{settings:this.settings,matrix:l,width:this.width,height:this.height,ratio:this.camera.ratio,scalingRatio:this.settings(m,"webglOversamplingRatio")}))}if(n)for(c=this.camera.quadtree.area(this.camera.getRectangle(this.width,this.height)),this.camera.applyView(a,a,{nodes:c,edges:[],width:this.width,height:this.height}),g=function(a){return i.settings({prefix:i.camera.prefix},a)},d=0,e=c.length;e>d;d++)c[d].hidden||(sigma.canvas.labels[c[d].type||this.settings(m,"defaultNodeType")]||sigma.canvas.labels.def)(c[d],this.contexts.labels,g);return this.dispatchEvent("render"),this},sigma.renderers.webgl.prototype.initDOM=function(a,b,c){var d=document.createElement(a),e=this;d.style.position="absolute",d.setAttribute("class","sigma-"+b),this.domElements[b]=d,this.container.appendChild(d),"canvas"===a.toLowerCase()&&(this.contexts[b]=d.getContext(c?"experimental-webgl":"2d",{preserveDrawingBuffer:!0}),c&&(d.addEventListener("webglcontextlost",function(a){a.preventDefault()},!1),d.addEventListener("webglcontextrestored",function(){e.render()},!1)))},sigma.renderers.webgl.prototype.resize=function(b,c){var d,e=this.width,f=this.height,g=sigma.utils.getPixelRatio();if(b!==a&&c!==a?(this.width=b,this.height=c):(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,b=this.width,c=this.height),e!==this.width||f!==this.height)for(d in this.domElements)this.domElements[d].style.width=b+"px",this.domElements[d].style.height=c+"px","canvas"===this.domElements[d].tagName.toLowerCase()&&(this.contexts[d]&&this.contexts[d].scale?(this.domElements[d].setAttribute("width",b*g+"px"),this.domElements[d].setAttribute("height",c*g+"px"),1!==g&&this.contexts[d].scale(g,g)):(this.domElements[d].setAttribute("width",b*this.settings("webglOversamplingRatio")+"px"),this.domElements[d].setAttribute("height",c*this.settings("webglOversamplingRatio")+"px")));for(d in this.contexts)this.contexts[d]&&this.contexts[d].viewport&&this.contexts[d].viewport(0,0,this.width*this.settings("webglOversamplingRatio"),this.height*this.settings("webglOversamplingRatio"));return this},sigma.renderers.webgl.prototype.clear=function(){return this.contexts.labels.clearRect(0,0,this.width,this.height),this.contexts.nodes.clear(this.contexts.nodes.COLOR_BUFFER_BIT),this.contexts.edges.clear(this.contexts.edges.COLOR_BUFFER_BIT),this},sigma.renderers.webgl.prototype.kill=function(){for(var a,b;b=this.captors.pop();)b.kill();delete this.captors;for(a in this.domElements)this.domElements[a].parentNode.removeChild(this.domElements[a]),delete this.domElements[a],delete this.contexts[a];delete this.domElements,delete this.contexts},sigma.utils.pkg("sigma.webgl.nodes"),sigma.utils.pkg("sigma.webgl.edges"),sigma.utils.pkg("sigma.canvas.labels")}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";if("undefined"==typeof conrad)throw"conrad is not declared";sigma.utils.pkg("sigma.renderers"),sigma.renderers.svg=function(a,b,c,d){if("object"!=typeof d)throw"sigma.renderers.svg: Wrong arguments.";if(!(d.container instanceof HTMLElement))throw"Container not found.";var e,f,g,h,i=this;for(sigma.classes.dispatcher.extend(this),this.graph=a,this.camera=b,this.domElements={graph:null,groups:{},nodes:{},edges:{},labels:{},hovers:{}},this.measurementCanvas=null,this.options=d,this.container=this.options.container,this.settings="object"==typeof d.settings&&d.settings?c.embedObjects(d.settings):c,this.settings("freeStyle",!!this.options.freeStyle),this.settings("xmlns","http://www.w3.org/2000/svg"),this.nodesOnScreen=[],this.edgesOnScreen=[],this.options.prefix="renderer"+sigma.utils.id()+":",this.initDOM("svg"),this.captors=[],g=this.options.captors||[sigma.captors.mouse,sigma.captors.touch],e=0,f=g.length;f>e;e++)h="function"==typeof g[e]?g[e]:sigma.captors[g[e]],this.captors.push(new h(this.domElements.graph,this.camera,this.settings));window.addEventListener("resize",function(){i.resize()}),sigma.misc.bindDOMEvents.call(this,this.domElements.graph),this.bindHovers(this.options.prefix),this.resize(!1)},sigma.renderers.svg.prototype.render=function(b){b=b||{};var c,d,e,f,g,h,i,j,k,l={},m=this.graph,n=this.graph.nodes,o=(this.options.prefix||"",this.settings(b,"drawEdges")),p=this.settings(b,"drawNodes"),q=(this.settings(b,"drawLabels"),this.settings.embedObjects(b,{prefix:this.options.prefix,forceLabels:this.options.forceLabels}));for(this.settings(b,"hideEdgesOnMove")&&(this.camera.isAnimated||this.camera.isMoving)&&(o=!1),this.camera.applyView(a,this.options.prefix,{width:this.width,height:this.height}),this.hideDOMElements(this.domElements.nodes),this.hideDOMElements(this.domElements.edges),this.hideDOMElements(this.domElements.labels),this.edgesOnScreen=[],this.nodesOnScreen=this.camera.quadtree.area(this.camera.getRectangle(this.width,this.height)),c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)l[c[d].id]=c[d];for(c=m.edges(),d=0,f=c.length;f>d;d++)g=c[d],!l[g.source]&&!l[g.target]||g.hidden||n(g.source).hidden||n(g.target).hidden||this.edgesOnScreen.push(g);if(j=sigma.svg.nodes,k=sigma.svg.labels,p)for(c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)c[d].hidden||this.domElements.nodes[c[d].id]||(e=(j[c[d].type]||j.def).create(c[d],q),this.domElements.nodes[c[d].id]=e,this.domElements.groups.nodes.appendChild(e),e=(k[c[d].type]||k.def).create(c[d],q),this.domElements.labels[c[d].id]=e,this.domElements.groups.labels.appendChild(e));if(p)for(c=this.nodesOnScreen,d=0,f=c.length;f>d;d++)c[d].hidden||((j[c[d].type]||j.def).update(c[d],this.domElements.nodes[c[d].id],q),(k[c[d].type]||k.def).update(c[d],this.domElements.labels[c[d].id],q));if(j=sigma.svg.edges,o)for(c=this.edgesOnScreen,d=0,f=c.length;f>d;d++)this.domElements.edges[c[d].id]||(h=n(c[d].source),i=n(c[d].target),e=(j[c[d].type]||j.def).create(c[d],h,i,q),this.domElements.edges[c[d].id]=e,this.domElements.groups.edges.appendChild(e));if(o)for(c=this.edgesOnScreen,d=0,f=c.length;f>d;d++)h=n(c[d].source),i=n(c[d].target),(j[c[d].type]||j.def).update(c[d],this.domElements.edges[c[d].id],h,i,q);return this.dispatchEvent("render"),this},sigma.renderers.svg.prototype.initDOM=function(a){var b,c,d,e=document.createElementNS(this.settings("xmlns"),a),f=this.settings("classPrefix");e.style.position="absolute",e.setAttribute("class",f+"-svg"),e.setAttribute("xmlns",this.settings("xmlns")),e.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),e.setAttribute("version","1.1");var g=document.createElement("canvas");g.setAttribute("class",f+"-measurement-canvas"),this.domElements.graph=this.container.appendChild(e);var h=["edges","nodes","labels","hovers"];for(d=0,c=h.length;c>d;d++)b=document.createElementNS(this.settings("xmlns"),"g"),b.setAttributeNS(null,"id",f+"-group-"+h[d]),b.setAttributeNS(null,"class",f+"-group"),this.domElements.groups[h[d]]=this.domElements.graph.appendChild(b);this.container.appendChild(g),this.measurementCanvas=g.getContext("2d")},sigma.renderers.svg.prototype.hideDOMElements=function(a){var b,c;for(c in a)b=a[c],sigma.svg.utils.hide(b);return this},sigma.renderers.svg.prototype.bindHovers=function(a){function b(b){var c=b.data.node,d=g.settings.embedObjects({prefix:a});if(d("enableHovering")){var h=(f[c.type]||f.def).create(c,g.domElements.nodes[c.id],g.measurementCanvas,d);g.domElements.hovers[c.id]=h,g.domElements.groups.hovers.appendChild(h),e=c}}function c(b){var c=b.data.node,d=g.settings.embedObjects({prefix:a});d("enableHovering")&&(g.domElements.groups.hovers.removeChild(g.domElements.hovers[c.id]),e=null,delete g.domElements.hovers[c.id],g.domElements.groups.nodes.appendChild(g.domElements.nodes[c.id]))}function d(){if(e){var b=g.settings.embedObjects({prefix:a});g.domElements.groups.hovers.removeChild(g.domElements.hovers[e.id]),delete g.domElements.hovers[e.id];var c=(f[e.type]||f.def).create(e,g.domElements.nodes[e.id],g.measurementCanvas,b);g.domElements.hovers[e.id]=c,g.domElements.groups.hovers.appendChild(c)}}var e,f=sigma.svg.hovers,g=this;this.bind("overNode",b),this.bind("outNode",c),this.bind("render",d)},sigma.renderers.svg.prototype.resize=function(b,c){var d=this.width,e=this.height,f=1;return b!==a&&c!==a?(this.width=b,this.height=c):(this.width=this.container.offsetWidth,this.height=this.container.offsetHeight,b=this.width,c=this.height),(d!==this.width||e!==this.height)&&(this.domElements.graph.style.width=b+"px",this.domElements.graph.style.height=c+"px","svg"===this.domElements.graph.tagName.toLowerCase()&&(this.domElements.graph.setAttribute("width",b*f),this.domElements.graph.setAttribute("height",c*f))),this},sigma.utils.pkg("sigma.svg.nodes"),sigma.utils.pkg("sigma.svg.edges"),sigma.utils.pkg("sigma.svg.labels")}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.renderers");var b,c=!!a.WebGLRenderingContext;if(c){b=document.createElement("canvas");try{c=!(!b.getContext("webgl")&&!b.getContext("experimental-webgl"))}catch(d){c=!1}}sigma.renderers.def=c?sigma.renderers.webgl:sigma.renderers.canvas}(this),function(){"use strict";sigma.utils.pkg("sigma.webgl.nodes"),sigma.webgl.nodes.def={POINTS:3,ATTRIBUTES:5,addNode:function(a,b,c,d,e){var f=sigma.utils.floatColor(a.color||e("defaultNodeColor"));b[c++]=a[d+"x"],b[c++]=a[d+"y"],b[c++]=a[d+"size"],b[c++]=f,b[c++]=0,b[c++]=a[d+"x"],b[c++]=a[d+"y"],b[c++]=a[d+"size"],b[c++]=f,b[c++]=2*Math.PI/3,b[c++]=a[d+"x"],b[c++]=a[d+"y"],b[c++]=a[d+"size"],b[c++]=f,b[c++]=4*Math.PI/3},render:function(a,b,c,d){var e,f=a.getAttribLocation(b,"a_position"),g=a.getAttribLocation(b,"a_size"),h=a.getAttribLocation(b,"a_color"),i=a.getAttribLocation(b,"a_angle"),j=a.getUniformLocation(b,"u_resolution"),k=a.getUniformLocation(b,"u_matrix"),l=a.getUniformLocation(b,"u_ratio"),m=a.getUniformLocation(b,"u_scale");e=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,e),a.bufferData(a.ARRAY_BUFFER,c,a.DYNAMIC_DRAW),a.uniform2f(j,d.width,d.height),a.uniform1f(l,1/Math.pow(d.ratio,d.settings("nodesPowRatio"))),a.uniform1f(m,d.scalingRatio),a.uniformMatrix3fv(k,!1,d.matrix),a.enableVertexAttribArray(f),a.enableVertexAttribArray(g),a.enableVertexAttribArray(h),a.enableVertexAttribArray(i),a.vertexAttribPointer(f,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,0),a.vertexAttribPointer(g,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,8),a.vertexAttribPointer(h,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,12),a.vertexAttribPointer(i,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,16),a.drawArrays(a.TRIANGLES,d.start||0,d.count||c.length/this.ATTRIBUTES)},initProgram:function(a){var b,c,d;return b=sigma.utils.loadShader(a,["attribute vec2 a_position;","attribute float a_size;","attribute float a_color;","attribute float a_angle;","uniform vec2 u_resolution;","uniform float u_ratio;","uniform float u_scale;","uniform mat3 u_matrix;","varying vec4 color;","varying vec2 center;","varying float radius;","void main() {","radius = a_size * u_ratio;","vec2 position = (u_matrix * vec3(a_position, 1)).xy;","center = position * u_scale;","center = vec2(center.x, u_scale * u_resolution.y - center.y);","position = position +","2.0 * radius * vec2(cos(a_angle), sin(a_angle));","position = (position / u_resolution * 2.0 - 1.0) * vec2(1, -1);","radius = radius * u_scale;","gl_Position = vec4(position, 0, 1);","float c = a_color;","color.b = mod(c, 256.0); c = floor(c / 256.0);","color.g = mod(c, 256.0); c = floor(c / 256.0);","color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;","color.a = 1.0;","}"].join("\n"),a.VERTEX_SHADER),c=sigma.utils.loadShader(a,["precision mediump float;","varying vec4 color;","varying vec2 center;","varying float radius;","void main(void) {","vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);","vec2 m = gl_FragCoord.xy - center;","float diff = radius - sqrt(m.x * m.x + m.y * m.y);","if (diff > 0.0)","gl_FragColor = color;","else","gl_FragColor = color0;","}"].join("\n"),a.FRAGMENT_SHADER),d=sigma.utils.loadProgram(a,[b,c])}}}(),function(){"use strict";sigma.utils.pkg("sigma.webgl.nodes"),sigma.webgl.nodes.fast={POINTS:1,ATTRIBUTES:4,addNode:function(a,b,c,d,e){b[c++]=a[d+"x"],b[c++]=a[d+"y"],b[c++]=a[d+"size"],b[c++]=sigma.utils.floatColor(a.color||e("defaultNodeColor"))},render:function(a,b,c,d){var e,f=a.getAttribLocation(b,"a_position"),g=a.getAttribLocation(b,"a_size"),h=a.getAttribLocation(b,"a_color"),i=a.getUniformLocation(b,"u_resolution"),j=a.getUniformLocation(b,"u_matrix"),k=a.getUniformLocation(b,"u_ratio"),l=a.getUniformLocation(b,"u_scale");e=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,e),a.bufferData(a.ARRAY_BUFFER,c,a.DYNAMIC_DRAW),a.uniform2f(i,d.width,d.height),a.uniform1f(k,1/Math.pow(d.ratio,d.settings("nodesPowRatio"))),a.uniform1f(l,d.scalingRatio),a.uniformMatrix3fv(j,!1,d.matrix),a.enableVertexAttribArray(f),a.enableVertexAttribArray(g),a.enableVertexAttribArray(h),a.vertexAttribPointer(f,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,0),a.vertexAttribPointer(g,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,8),a.vertexAttribPointer(h,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,12),a.drawArrays(a.POINTS,d.start||0,d.count||c.length/this.ATTRIBUTES)},initProgram:function(a){var b,c,d;return b=sigma.utils.loadShader(a,["attribute vec2 a_position;","attribute float a_size;","attribute float a_color;","uniform vec2 u_resolution;","uniform float u_ratio;","uniform float u_scale;","uniform mat3 u_matrix;","varying vec4 color;","void main() {","gl_Position = vec4(","((u_matrix * vec3(a_position, 1)).xy /","u_resolution * 2.0 - 1.0) * vec2(1, -1),","0,","1",");","gl_PointSize = a_size * u_ratio * u_scale * 2.0;","float c = a_color;","color.b = mod(c, 256.0); c = floor(c / 256.0);","color.g = mod(c, 256.0); c = floor(c / 256.0);","color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;","color.a = 1.0;","}"].join("\n"),a.VERTEX_SHADER),c=sigma.utils.loadShader(a,["precision mediump float;","varying vec4 color;","void main(void) {","float border = 0.01;","float radius = 0.5;","vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);","vec2 m = gl_PointCoord - vec2(0.5, 0.5);","float dist = radius - sqrt(m.x * m.x + m.y * m.y);","float t = 0.0;","if (dist > border)","t = 1.0;","else if (dist > 0.0)","t = dist / border;","gl_FragColor = mix(color0, color, t);","}"].join("\n"),a.FRAGMENT_SHADER),d=sigma.utils.loadProgram(a,[b,c])}}}(),function(){"use strict";sigma.utils.pkg("sigma.webgl.edges"),sigma.webgl.edges.def={POINTS:6,ATTRIBUTES:7,addEdge:function(a,b,c,d,e,f,g){var h=(a[f+"size"]||1)/2,i=b[f+"x"],j=b[f+"y"],k=c[f+"x"],l=c[f+"y"],m=a.color;if(!m)switch(g("edgeColor")){case"source":m=b.color||g("defaultNodeColor");break;case"target":m=c.color||g("defaultNodeColor");break;default:m=g("defaultEdgeColor")}m=sigma.utils.floatColor(m),d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=0,d[e++]=m,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=1,d[e++]=m,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=0,d[e++]=m,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=0,d[e++]=m,d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=1,d[e++]=m,d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=0,d[e++]=m},render:function(a,b,c,d){var e,f=a.getAttribLocation(b,"a_color"),g=a.getAttribLocation(b,"a_position1"),h=a.getAttribLocation(b,"a_position2"),i=a.getAttribLocation(b,"a_thickness"),j=a.getAttribLocation(b,"a_minus"),k=a.getUniformLocation(b,"u_resolution"),l=a.getUniformLocation(b,"u_matrix"),m=a.getUniformLocation(b,"u_matrixHalfPi"),n=a.getUniformLocation(b,"u_matrixHalfPiMinus"),o=a.getUniformLocation(b,"u_ratio"),p=a.getUniformLocation(b,"u_scale");e=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,e),a.bufferData(a.ARRAY_BUFFER,c,a.STATIC_DRAW),a.uniform2f(k,d.width,d.height),a.uniform1f(o,d.ratio/Math.pow(d.ratio,d.settings("edgesPowRatio"))),a.uniform1f(p,d.scalingRatio),a.uniformMatrix3fv(l,!1,d.matrix),a.uniformMatrix2fv(m,!1,sigma.utils.matrices.rotation(Math.PI/2,!0)),a.uniformMatrix2fv(n,!1,sigma.utils.matrices.rotation(-Math.PI/2,!0)),a.enableVertexAttribArray(f),a.enableVertexAttribArray(g),a.enableVertexAttribArray(h),a.enableVertexAttribArray(i),a.enableVertexAttribArray(j),a.vertexAttribPointer(g,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,0),a.vertexAttribPointer(h,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,8),a.vertexAttribPointer(i,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,16),a.vertexAttribPointer(j,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,20),a.vertexAttribPointer(f,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,24),a.drawArrays(a.TRIANGLES,d.start||0,d.count||c.length/this.ATTRIBUTES)},initProgram:function(a){var b,c,d;return b=sigma.utils.loadShader(a,["attribute vec2 a_position1;","attribute vec2 a_position2;","attribute float a_thickness;","attribute float a_minus;","attribute float a_color;","uniform vec2 u_resolution;","uniform float u_ratio;","uniform float u_scale;","uniform mat3 u_matrix;","uniform mat2 u_matrixHalfPi;","uniform mat2 u_matrixHalfPiMinus;","varying vec4 color;","void main() {","vec2 position = a_thickness * u_ratio *","normalize(a_position2 - a_position1);","mat2 matrix = a_minus * u_matrixHalfPiMinus +","(1.0 - a_minus) * u_matrixHalfPi;","position = matrix * position + a_position1;","gl_Position = vec4(","((u_matrix * vec3(position, 1)).xy /","u_resolution * 2.0 - 1.0) * vec2(1, -1),","0,","1",");","float c = a_color;","color.b = mod(c, 256.0); c = floor(c / 256.0);","color.g = mod(c, 256.0); c = floor(c / 256.0);","color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;","color.a = 1.0;","}"].join("\n"),a.VERTEX_SHADER),c=sigma.utils.loadShader(a,["precision mediump float;","varying vec4 color;","void main(void) {","gl_FragColor = color;","}"].join("\n"),a.FRAGMENT_SHADER),d=sigma.utils.loadProgram(a,[b,c])}}}(),function(){"use strict";sigma.utils.pkg("sigma.webgl.edges"),sigma.webgl.edges.fast={POINTS:2,ATTRIBUTES:3,addEdge:function(a,b,c,d,e,f,g){var h=((a[f+"size"]||1)/2,b[f+"x"]),i=b[f+"y"],j=c[f+"x"],k=c[f+"y"],l=a.color;if(!l)switch(g("edgeColor")){case"source":l=b.color||g("defaultNodeColor");break;case"target":l=c.color||g("defaultNodeColor");break;default:l=g("defaultEdgeColor")}l=sigma.utils.floatColor(l),d[e++]=h,d[e++]=i,d[e++]=l,d[e++]=j,d[e++]=k,d[e++]=l},render:function(a,b,c,d){var e,f=a.getAttribLocation(b,"a_color"),g=a.getAttribLocation(b,"a_position"),h=a.getUniformLocation(b,"u_resolution"),i=a.getUniformLocation(b,"u_matrix");e=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,e),a.bufferData(a.ARRAY_BUFFER,c,a.DYNAMIC_DRAW),a.uniform2f(h,d.width,d.height),a.uniformMatrix3fv(i,!1,d.matrix),a.enableVertexAttribArray(g),a.enableVertexAttribArray(f),a.vertexAttribPointer(g,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,0),a.vertexAttribPointer(f,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,8),a.lineWidth(3),a.drawArrays(a.LINES,d.start||0,d.count||c.length/this.ATTRIBUTES)},initProgram:function(a){var b,c,d;return b=sigma.utils.loadShader(a,["attribute vec2 a_position;","attribute float a_color;","uniform vec2 u_resolution;","uniform mat3 u_matrix;","varying vec4 color;","void main() {","gl_Position = vec4(","((u_matrix * vec3(a_position, 1)).xy /","u_resolution * 2.0 - 1.0) * vec2(1, -1),","0,","1",");","float c = a_color;","color.b = mod(c, 256.0); c = floor(c / 256.0);","color.g = mod(c, 256.0); c = floor(c / 256.0);","color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;","color.a = 1.0;","}"].join("\n"),a.VERTEX_SHADER),c=sigma.utils.loadShader(a,["precision mediump float;","varying vec4 color;","void main(void) {","gl_FragColor = color;","}"].join("\n"),a.FRAGMENT_SHADER),d=sigma.utils.loadProgram(a,[b,c])}}}(),function(){"use strict";sigma.utils.pkg("sigma.webgl.edges"),sigma.webgl.edges.arrow={POINTS:9,ATTRIBUTES:11,addEdge:function(a,b,c,d,e,f,g){var h=(a[f+"size"]||1)/2,i=b[f+"x"],j=b[f+"y"],k=c[f+"x"],l=c[f+"y"],m=c[f+"size"],n=a.color;if(!n)switch(g("edgeColor")){case"source":n=b.color||g("defaultNodeColor");break;case"target":n=c.color||g("defaultNodeColor");break;default:n=g("defaultEdgeColor")}n=sigma.utils.floatColor(n),d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=m,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=1,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=m,d[e++]=0,d[e++]=1,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=i,d[e++]=j,d[e++]=k,d[e++]=l,d[e++]=h,d[e++]=m,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=0,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=0,d[e++]=1,d[e++]=-1,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=0,d[e++]=1,d[e++]=0,d[e++]=n,d[e++]=k,d[e++]=l,d[e++]=i,d[e++]=j,d[e++]=h,d[e++]=m,d[e++]=1,d[e++]=0,d[e++]=1,d[e++]=1,d[e++]=n},render:function(a,b,c,d){var e,f=a.getAttribLocation(b,"a_pos1"),g=a.getAttribLocation(b,"a_pos2"),h=a.getAttribLocation(b,"a_thickness"),i=a.getAttribLocation(b,"a_tSize"),j=a.getAttribLocation(b,"a_delay"),k=a.getAttribLocation(b,"a_minus"),l=a.getAttribLocation(b,"a_head"),m=a.getAttribLocation(b,"a_headPosition"),n=a.getAttribLocation(b,"a_color"),o=a.getUniformLocation(b,"u_resolution"),p=a.getUniformLocation(b,"u_matrix"),q=a.getUniformLocation(b,"u_matrixHalfPi"),r=a.getUniformLocation(b,"u_matrixHalfPiMinus"),s=a.getUniformLocation(b,"u_ratio"),t=a.getUniformLocation(b,"u_nodeRatio"),u=a.getUniformLocation(b,"u_arrowHead"),v=a.getUniformLocation(b,"u_scale");e=a.createBuffer(),a.bindBuffer(a.ARRAY_BUFFER,e),a.bufferData(a.ARRAY_BUFFER,c,a.STATIC_DRAW),a.uniform2f(o,d.width,d.height),a.uniform1f(s,d.ratio/Math.pow(d.ratio,d.settings("edgesPowRatio"))),a.uniform1f(t,Math.pow(d.ratio,d.settings("nodesPowRatio"))/d.ratio),a.uniform1f(u,5),a.uniform1f(v,d.scalingRatio),a.uniformMatrix3fv(p,!1,d.matrix),a.uniformMatrix2fv(q,!1,sigma.utils.matrices.rotation(Math.PI/2,!0)),a.uniformMatrix2fv(r,!1,sigma.utils.matrices.rotation(-Math.PI/2,!0)),a.enableVertexAttribArray(f),a.enableVertexAttribArray(g),a.enableVertexAttribArray(h),a.enableVertexAttribArray(i),a.enableVertexAttribArray(j),a.enableVertexAttribArray(k),a.enableVertexAttribArray(l),a.enableVertexAttribArray(m),a.enableVertexAttribArray(n),a.vertexAttribPointer(f,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,0),a.vertexAttribPointer(g,2,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,8),a.vertexAttribPointer(h,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,16),a.vertexAttribPointer(i,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,20),a.vertexAttribPointer(j,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,24),a.vertexAttribPointer(k,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,28),a.vertexAttribPointer(l,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,32),a.vertexAttribPointer(m,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,36),a.vertexAttribPointer(n,1,a.FLOAT,!1,this.ATTRIBUTES*Float32Array.BYTES_PER_ELEMENT,40),a.drawArrays(a.TRIANGLES,d.start||0,d.count||c.length/this.ATTRIBUTES)},initProgram:function(a){var b,c,d;return b=sigma.utils.loadShader(a,["attribute vec2 a_pos1;","attribute vec2 a_pos2;","attribute float a_thickness;","attribute float a_tSize;","attribute float a_delay;","attribute float a_minus;","attribute float a_head;","attribute float a_headPosition;","attribute float a_color;","uniform vec2 u_resolution;","uniform float u_ratio;","uniform float u_nodeRatio;","uniform float u_arrowHead;","uniform float u_scale;","uniform mat3 u_matrix;","uniform mat2 u_matrixHalfPi;","uniform mat2 u_matrixHalfPiMinus;","varying vec4 color;","void main() {","vec2 pos = normalize(a_pos2 - a_pos1);","mat2 matrix = (1.0 - a_head) *","(","a_minus * u_matrixHalfPiMinus +","(1.0 - a_minus) * u_matrixHalfPi",") + a_head * (","a_headPosition * u_matrixHalfPiMinus * 0.6 +","(a_headPosition * a_headPosition - 1.0) * mat2(1.0)",");","pos = a_pos1 + (","(1.0 - a_head) * a_thickness * u_ratio * matrix * pos +","a_head * u_arrowHead * a_thickness * u_ratio * matrix * pos +","a_delay * pos * (","a_tSize / u_nodeRatio +","u_arrowHead * a_thickness * u_ratio",")",");","gl_Position = vec4(","((u_matrix * vec3(pos, 1)).xy /","u_resolution * 2.0 - 1.0) * vec2(1, -1),","0,","1",");","float c = a_color;","color.b = mod(c, 256.0); c = floor(c / 256.0);","color.g = mod(c, 256.0); c = floor(c / 256.0);","color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;","color.a = 1.0;","}"].join("\n"),a.VERTEX_SHADER),c=sigma.utils.loadShader(a,["precision mediump float;","varying vec4 color;","void main(void) {","gl_FragColor = color;","}"].join("\n"),a.FRAGMENT_SHADER),d=sigma.utils.loadProgram(a,[b,c])}}}(),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.labels"),sigma.canvas.labels.def=function(a,b,c){var d,e=c("prefix")||"",f=a[e+"size"];f<c("labelThreshold")||a.label&&"string"==typeof a.label&&(d="fixed"===c("labelSize")?c("defaultLabelSize"):c("labelSizeRatio")*f,b.font=(c("fontStyle")?c("fontStyle")+" ":"")+d+"px "+c("font"),b.fillStyle="node"===c("labelColor")?a.color||c("defaultNodeColor"):c("defaultLabelColor"),b.fillText(a.label,Math.round(a[e+"x"]+f+3),Math.round(a[e+"y"]+d/3)))}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.hovers"),sigma.canvas.hovers.def=function(a,b,c){var d,e,f,g,h,i=c("hoverFontStyle")||c("fontStyle"),j=c("prefix")||"",k=a[j+"size"],l="fixed"===c("labelSize")?c("defaultLabelSize"):c("labelSizeRatio")*k;b.font=(i?i+" ":"")+l+"px "+(c("hoverFont")||c("font")),b.beginPath(),b.fillStyle="node"===c("labelHoverBGColor")?a.color||c("defaultNodeColor"):c("defaultHoverLabelBGColor"),a.label&&c("labelHoverShadow")&&(b.shadowOffsetX=0,b.shadowOffsetY=0,b.shadowBlur=8,b.shadowColor=c("labelHoverShadowColor")),a.label&&"string"==typeof a.label&&(d=Math.round(a[j+"x"]-l/2-2),e=Math.round(a[j+"y"]-l/2-2),f=Math.round(b.measureText(a.label).width+l/2+k+7),g=Math.round(l+4),h=Math.round(l/2+2),b.moveTo(d,e+h),b.arcTo(d,e,d+h,e,h),b.lineTo(d+f,e),b.lineTo(d+f,e+g),b.lineTo(d+h,e+g),b.arcTo(d,e+g,d,e+g-h,h),b.lineTo(d,e+h),b.closePath(),b.fill(),b.shadowOffsetX=0,b.shadowOffsetY=0,b.shadowBlur=0),c("borderSize")>0&&(b.beginPath(),b.fillStyle="node"===c("nodeBorderColor")?a.color||c("defaultNodeColor"):c("defaultNodeBorderColor"),b.arc(a[j+"x"],a[j+"y"],k+c("borderSize"),0,2*Math.PI,!0),b.closePath(),b.fill());var m=sigma.canvas.nodes[a.type]||sigma.canvas.nodes.def;m(a,b,c),a.label&&"string"==typeof a.label&&(b.fillStyle="node"===c("labelHoverColor")?a.color||c("defaultNodeColor"):c("defaultLabelHoverColor"),b.fillText(a.label,Math.round(a[j+"x"]+k+3),Math.round(a[j+"y"]+l/3)))}}.call(this),function(){"use strict";sigma.utils.pkg("sigma.canvas.nodes"),sigma.canvas.nodes.def=function(a,b,c){var d=c("prefix")||"";b.fillStyle=a.color||c("defaultNodeColor"),b.beginPath(),b.arc(a[d+"x"],a[d+"y"],a[d+"size"],0,2*Math.PI,!0),b.closePath(),b.fill()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edges"),sigma.canvas.edges.def=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=a[g+"size"]||1,i=e("edgeColor"),j=e("defaultNodeColor"),k=e("defaultEdgeColor");if(!f)switch(i){case"source":f=b.color||j;break;case"target":f=c.color||j;break;default:f=k}d.strokeStyle=f,d.lineWidth=h,d.beginPath(),d.moveTo(b[g+"x"],b[g+"y"]),d.lineTo(c[g+"x"],c[g+"y"]),d.stroke()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edges"),sigma.canvas.edges.curve=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=a[g+"size"]||1,i=e("edgeColor"),j=e("defaultNodeColor"),k=e("defaultEdgeColor"),l={},m=b[g+"size"],n=b[g+"x"],o=b[g+"y"],p=c[g+"x"],q=c[g+"y"];if(l=b.id===c.id?sigma.utils.getSelfLoopControlPoints(n,o,m):sigma.utils.getQuadraticControlPoint(n,o,p,q),!f)switch(i){case"source":f=b.color||j;break;case"target":f=c.color||j;break;default:f=k}d.strokeStyle=f,d.lineWidth=h,d.beginPath(),d.moveTo(n,o),b.id===c.id?d.bezierCurveTo(l.x1,l.y1,l.x2,l.y2,p,q):d.quadraticCurveTo(l.x,l.y,p,q),d.stroke()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edges"),sigma.canvas.edges.arrow=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=e("edgeColor"),i=e("defaultNodeColor"),j=e("defaultEdgeColor"),k=a[g+"size"]||1,l=c[g+"size"],m=b[g+"x"],n=b[g+"y"],o=c[g+"x"],p=c[g+"y"],q=Math.max(2.5*k,e("minArrowSize")),r=Math.sqrt(Math.pow(o-m,2)+Math.pow(p-n,2)),s=m+(o-m)*(r-q-l)/r,t=n+(p-n)*(r-q-l)/r,u=(o-m)*q/r,v=(p-n)*q/r;if(!f)switch(h){case"source":f=b.color||i;break;case"target":f=c.color||i;break;default:f=j}d.strokeStyle=f,d.lineWidth=k,d.beginPath(),d.moveTo(m,n),d.lineTo(s,t),d.stroke(),d.fillStyle=f,d.beginPath(),d.moveTo(s+u,t+v),d.lineTo(s+.6*v,t-.6*u),d.lineTo(s-.6*v,t+.6*u),d.lineTo(s+u,t+v),d.closePath(),d.fill()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edges"),sigma.canvas.edges.curvedArrow=function(a,b,c,d,e){var f,g,h,i,j,k=a.color,l=e("prefix")||"",m=e("edgeColor"),n=e("defaultNodeColor"),o=e("defaultEdgeColor"),p={},q=a[l+"size"]||1,r=c[l+"size"],s=b[l+"x"],t=b[l+"y"],u=c[l+"x"],v=c[l+"y"],w=Math.max(2.5*q,e("minArrowSize"));if(p=b.id===c.id?sigma.utils.getSelfLoopControlPoints(s,t,r):sigma.utils.getQuadraticControlPoint(s,t,u,v),b.id===c.id?(f=Math.sqrt(Math.pow(u-p.x1,2)+Math.pow(v-p.y1,2)),g=p.x1+(u-p.x1)*(f-w-r)/f,h=p.y1+(v-p.y1)*(f-w-r)/f,i=(u-p.x1)*w/f,j=(v-p.y1)*w/f):(f=Math.sqrt(Math.pow(u-p.x,2)+Math.pow(v-p.y,2)),g=p.x+(u-p.x)*(f-w-r)/f,h=p.y+(v-p.y)*(f-w-r)/f,i=(u-p.x)*w/f,j=(v-p.y)*w/f),!k)switch(m){case"source":k=b.color||n;break;case"target":k=c.color||n;break;default:k=o}d.strokeStyle=k,d.lineWidth=q,d.beginPath(),d.moveTo(s,t),b.id===c.id?d.bezierCurveTo(p.x2,p.y2,p.x1,p.y1,g,h):d.quadraticCurveTo(p.x,p.y,g,h),d.stroke(),d.fillStyle=k,d.beginPath(),d.moveTo(g+i,h+j),d.lineTo(g+.6*j,h-.6*i),d.lineTo(g-.6*j,h+.6*i),d.lineTo(g+i,h+j),d.closePath(),d.fill()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edgehovers"),sigma.canvas.edgehovers.def=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=a[g+"size"]||1,i=e("edgeColor"),j=e("defaultNodeColor"),k=e("defaultEdgeColor");if(!f)switch(i){case"source":f=b.color||j;break;case"target":f=c.color||j;break;default:f=k}f="edge"===e("edgeHoverColor")?a.hover_color||f:a.hover_color||e("defaultEdgeHoverColor")||f,h*=e("edgeHoverSizeRatio"),d.strokeStyle=f,d.lineWidth=h,d.beginPath(),d.moveTo(b[g+"x"],b[g+"y"]),d.lineTo(c[g+"x"],c[g+"y"]),d.stroke()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edgehovers"),sigma.canvas.edgehovers.curve=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=e("edgeHoverSizeRatio")*(a[g+"size"]||1),i=e("edgeColor"),j=e("defaultNodeColor"),k=e("defaultEdgeColor"),l={},m=b[g+"size"],n=b[g+"x"],o=b[g+"y"],p=c[g+"x"],q=c[g+"y"];if(l=b.id===c.id?sigma.utils.getSelfLoopControlPoints(n,o,m):sigma.utils.getQuadraticControlPoint(n,o,p,q),!f)switch(i){case"source":f=b.color||j;break;case"target":f=c.color||j;break;default:f=k}f="edge"===e("edgeHoverColor")?a.hover_color||f:a.hover_color||e("defaultEdgeHoverColor")||f,d.strokeStyle=f,d.lineWidth=h,d.beginPath(),d.moveTo(n,o),b.id===c.id?d.bezierCurveTo(l.x1,l.y1,l.x2,l.y2,p,q):d.quadraticCurveTo(l.x,l.y,p,q),d.stroke()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edgehovers"),sigma.canvas.edgehovers.arrow=function(a,b,c,d,e){var f=a.color,g=e("prefix")||"",h=e("edgeColor"),i=e("defaultNodeColor"),j=e("defaultEdgeColor"),k=a[g+"size"]||1,l=c[g+"size"],m=b[g+"x"],n=b[g+"y"],o=c[g+"x"],p=c[g+"y"];
+k=a.hover?e("edgeHoverSizeRatio")*k:k;var q=2.5*k,r=Math.sqrt(Math.pow(o-m,2)+Math.pow(p-n,2)),s=m+(o-m)*(r-q-l)/r,t=n+(p-n)*(r-q-l)/r,u=(o-m)*q/r,v=(p-n)*q/r;if(!f)switch(h){case"source":f=b.color||i;break;case"target":f=c.color||i;break;default:f=j}f="edge"===e("edgeHoverColor")?a.hover_color||f:a.hover_color||e("defaultEdgeHoverColor")||f,d.strokeStyle=f,d.lineWidth=k,d.beginPath(),d.moveTo(m,n),d.lineTo(s,t),d.stroke(),d.fillStyle=f,d.beginPath(),d.moveTo(s+u,t+v),d.lineTo(s+.6*v,t-.6*u),d.lineTo(s-.6*v,t+.6*u),d.lineTo(s+u,t+v),d.closePath(),d.fill()}}(),function(){"use strict";sigma.utils.pkg("sigma.canvas.edgehovers"),sigma.canvas.edgehovers.curvedArrow=function(a,b,c,d,e){var f,g,h,i,j,k,l=a.color,m=e("prefix")||"",n=e("edgeColor"),o=e("defaultNodeColor"),p=e("defaultEdgeColor"),q={},r=e("edgeHoverSizeRatio")*(a[m+"size"]||1),s=c[m+"size"],t=b[m+"x"],u=b[m+"y"],v=c[m+"x"],w=c[m+"y"];if(q=b.id===c.id?sigma.utils.getSelfLoopControlPoints(t,u,s):sigma.utils.getQuadraticControlPoint(t,u,v,w),b.id===c.id?(f=Math.sqrt(Math.pow(v-q.x1,2)+Math.pow(w-q.y1,2)),g=2.5*r,h=q.x1+(v-q.x1)*(f-g-s)/f,i=q.y1+(w-q.y1)*(f-g-s)/f,j=(v-q.x1)*g/f,k=(w-q.y1)*g/f):(f=Math.sqrt(Math.pow(v-q.x,2)+Math.pow(w-q.y,2)),g=2.5*r,h=q.x+(v-q.x)*(f-g-s)/f,i=q.y+(w-q.y)*(f-g-s)/f,j=(v-q.x)*g/f,k=(w-q.y)*g/f),!l)switch(n){case"source":l=b.color||o;break;case"target":l=c.color||o;break;default:l=p}l="edge"===e("edgeHoverColor")?a.hover_color||l:a.hover_color||e("defaultEdgeHoverColor")||l,d.strokeStyle=l,d.lineWidth=r,d.beginPath(),d.moveTo(t,u),b.id===c.id?d.bezierCurveTo(q.x2,q.y2,q.x1,q.y1,h,i):d.quadraticCurveTo(q.x,q.y,h,i),d.stroke(),d.fillStyle=l,d.beginPath(),d.moveTo(h+j,i+k),d.lineTo(h+.6*k,i-.6*j),d.lineTo(h-.6*k,i+.6*j),d.lineTo(h+j,i+k),d.closePath(),d.fill()}}(),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.canvas.extremities"),sigma.canvas.extremities.def=function(a,b,c,d,e){(sigma.canvas.hovers[b.type]||sigma.canvas.hovers.def)(b,d,e),(sigma.canvas.hovers[c.type]||sigma.canvas.hovers.def)(c,d,e)}}.call(this),function(){"use strict";sigma.utils.pkg("sigma.svg.utils"),sigma.svg.utils={show:function(a){return a.style.display="",this},hide:function(a){return a.style.display="none",this}}}(),function(){"use strict";sigma.utils.pkg("sigma.svg.nodes"),sigma.svg.nodes.def={create:function(a,b){var c=(b("prefix")||"",document.createElementNS(b("xmlns"),"circle"));return c.setAttributeNS(null,"data-node-id",a.id),c.setAttributeNS(null,"class",b("classPrefix")+"-node"),c.setAttributeNS(null,"fill",a.color||b("defaultNodeColor")),c},update:function(a,b,c){var d=c("prefix")||"";return b.setAttributeNS(null,"cx",a[d+"x"]),b.setAttributeNS(null,"cy",a[d+"y"]),b.setAttributeNS(null,"r",a[d+"size"]),c("freeStyle")||b.setAttributeNS(null,"fill",a.color||c("defaultNodeColor")),b.style.display="",this}}}(),function(){"use strict";sigma.utils.pkg("sigma.svg.edges"),sigma.svg.edges.def={create:function(a,b,c,d){var e=a.color,f=(d("prefix")||"",d("edgeColor")),g=d("defaultNodeColor"),h=d("defaultEdgeColor");if(!e)switch(f){case"source":e=b.color||g;break;case"target":e=c.color||g;break;default:e=h}var i=document.createElementNS(d("xmlns"),"line");return i.setAttributeNS(null,"data-edge-id",a.id),i.setAttributeNS(null,"class",d("classPrefix")+"-edge"),i.setAttributeNS(null,"stroke",e),i},update:function(a,b,c,d,e){var f=e("prefix")||"";return b.setAttributeNS(null,"stroke-width",a[f+"size"]||1),b.setAttributeNS(null,"x1",c[f+"x"]),b.setAttributeNS(null,"y1",c[f+"y"]),b.setAttributeNS(null,"x2",d[f+"x"]),b.setAttributeNS(null,"y2",d[f+"y"]),b.style.display="",this}}}(),function(){"use strict";sigma.utils.pkg("sigma.svg.edges"),sigma.svg.edges.curve={create:function(a,b,c,d){var e=a.color,f=(d("prefix")||"",d("edgeColor")),g=d("defaultNodeColor"),h=d("defaultEdgeColor");if(!e)switch(f){case"source":e=b.color||g;break;case"target":e=c.color||g;break;default:e=h}var i=document.createElementNS(d("xmlns"),"path");return i.setAttributeNS(null,"data-edge-id",a.id),i.setAttributeNS(null,"class",d("classPrefix")+"-edge"),i.setAttributeNS(null,"stroke",e),i},update:function(a,b,c,d,e){var f=e("prefix")||"";b.setAttributeNS(null,"stroke-width",a[f+"size"]||1);var g=(c[f+"x"]+d[f+"x"])/2+(d[f+"y"]-c[f+"y"])/4,h=(c[f+"y"]+d[f+"y"])/2+(c[f+"x"]-d[f+"x"])/4,i="M"+c[f+"x"]+","+c[f+"y"]+" Q"+g+","+h+" "+d[f+"x"]+","+d[f+"y"];return b.setAttributeNS(null,"d",i),b.setAttributeNS(null,"fill","none"),b.style.display="",this}}}(),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.svg.labels"),sigma.svg.labels.def={create:function(a,b){var c=b("prefix")||"",d=a[c+"size"],e=document.createElementNS(b("xmlns"),"text"),f="fixed"===b("labelSize")?b("defaultLabelSize"):b("labelSizeRatio")*d,g="node"===b("labelColor")?a.color||b("defaultNodeColor"):b("defaultLabelColor");return e.setAttributeNS(null,"data-label-target",a.id),e.setAttributeNS(null,"class",b("classPrefix")+"-label"),e.setAttributeNS(null,"font-size",f),e.setAttributeNS(null,"font-family",b("font")),e.setAttributeNS(null,"fill",g),e.innerHTML=a.label,e.textContent=a.label,e},update:function(a,b,c){var d=c("prefix")||"",e=a[d+"size"],f="fixed"===c("labelSize")?c("defaultLabelSize"):c("labelSizeRatio")*e;return!c("forceLabels")&&e<c("labelThreshold")||"string"!=typeof a.label?void 0:(b.setAttributeNS(null,"x",Math.round(a[d+"x"]+e+3)),b.setAttributeNS(null,"y",Math.round(a[d+"y"]+f/3)),b.style.display="",this)}}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.svg.hovers"),sigma.svg.hovers.def={create:function(a,b,c,d){var e,f,g,h,i,j=(d("hoverFontStyle")||d("fontStyle"),d("prefix")||""),k=a[j+"size"],l="fixed"===d("labelSize")?d("defaultLabelSize"):d("labelSizeRatio")*k,m="node"===d("labelHoverColor")?a.color||d("defaultNodeColor"):d("defaultLabelHoverColor"),n=document.createElementNS(d("xmlns"),"g"),o=document.createElementNS(d("xmlns"),"rect"),p=document.createElementNS(d("xmlns"),"circle"),q=document.createElementNS(d("xmlns"),"text");return n.setAttributeNS(null,"class",d("classPrefix")+"-hover"),n.setAttributeNS(null,"data-node-id",a.id),"string"==typeof a.label&&(q.innerHTML=a.label,q.textContent=a.label,q.setAttributeNS(null,"class",d("classPrefix")+"-hover-label"),q.setAttributeNS(null,"font-size",l),q.setAttributeNS(null,"font-family",d("font")),q.setAttributeNS(null,"fill",m),q.setAttributeNS(null,"x",Math.round(a[j+"x"]+k+3)),q.setAttributeNS(null,"y",Math.round(a[j+"y"]+l/3)),e=Math.round(a[j+"x"]-l/2-2),f=Math.round(a[j+"y"]-l/2-2),g=Math.round(c.measureText(a.label).width+l/2+k+9),h=Math.round(l+4),i=Math.round(l/2+2),p.setAttributeNS(null,"class",d("classPrefix")+"-hover-area"),p.setAttributeNS(null,"fill","#fff"),p.setAttributeNS(null,"cx",a[j+"x"]),p.setAttributeNS(null,"cy",a[j+"y"]),p.setAttributeNS(null,"r",i),o.setAttributeNS(null,"class",d("classPrefix")+"-hover-area"),o.setAttributeNS(null,"fill","#fff"),o.setAttributeNS(null,"x",a[j+"x"]+i/4),o.setAttributeNS(null,"y",a[j+"y"]-i),o.setAttributeNS(null,"width",g),o.setAttributeNS(null,"height",h)),n.appendChild(p),n.appendChild(o),n.appendChild(q),n.appendChild(b),n}}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.middlewares"),sigma.utils.pkg("sigma.utils"),sigma.middlewares.rescale=function(a,b,c){var d,e,f,g,h,i,j,k,l=this.graph.nodes(),m=this.graph.edges(),n=this.settings.embedObjects(c||{}),o=n("bounds")||sigma.utils.getBoundaries(this.graph,a,!0),p=o.minX,q=o.minY,r=o.maxX,s=o.maxY,t=o.sizeMax,u=o.weightMax,v=n("width")||1,w=n("height")||1,x=n("autoRescale"),y={nodePosition:1,nodeSize:1,edgeSize:1};for(x instanceof Array||(x=["nodePosition","nodeSize","edgeSize"]),d=0,e=x.length;e>d;d++)if(!y[x[d]])throw new Error('The rescale setting "'+x[d]+'" is not recognized.');var z=~x.indexOf("nodePosition"),A=~x.indexOf("nodeSize"),B=~x.indexOf("edgeSize");for(j="outside"===n("scalingMode")?Math.max(v/Math.max(r-p,1),w/Math.max(s-q,1)):Math.min(v/Math.max(r-p,1),w/Math.max(s-q,1)),k=(n("rescaleIgnoreSize")?0:(n("maxNodeSize")||t)/j)+(n("sideMargin")||0),r+=k,p-=k,s+=k,q-=k,j="outside"===n("scalingMode")?Math.max(v/Math.max(r-p,1),w/Math.max(s-q,1)):Math.min(v/Math.max(r-p,1),w/Math.max(s-q,1)),n("maxNodeSize")||n("minNodeSize")?n("maxNodeSize")===n("minNodeSize")?(f=0,g=+n("maxNodeSize")):(f=(n("maxNodeSize")-n("minNodeSize"))/t,g=+n("minNodeSize")):(f=1,g=0),n("maxEdgeSize")||n("minEdgeSize")?n("maxEdgeSize")===n("minEdgeSize")?(h=0,i=+n("minEdgeSize")):(h=(n("maxEdgeSize")-n("minEdgeSize"))/u,i=+n("minEdgeSize")):(h=1,i=0),d=0,e=m.length;e>d;d++)m[d][b+"size"]=m[d][a+"size"]*(B?h:1)+(B?i:0);for(d=0,e=l.length;e>d;d++)l[d][b+"size"]=l[d][a+"size"]*(A?f:1)+(A?g:0),l[d][b+"x"]=(l[d][a+"x"]-(r+p)/2)*(z?j:1),l[d][b+"y"]=(l[d][a+"y"]-(s+q)/2)*(z?j:1)},sigma.utils.getBoundaries=function(a,b,c){var d,e,f=a.edges(),g=a.nodes(),h=-1/0,i=-1/0,j=1/0,k=1/0,l=-1/0,m=-1/0;if(c)for(d=0,e=f.length;e>d;d++)h=Math.max(f[d][b+"size"],h);for(d=0,e=g.length;e>d;d++)i=Math.max(g[d][b+"size"],i),l=Math.max(g[d][b+"x"],l),j=Math.min(g[d][b+"x"],j),m=Math.max(g[d][b+"y"],m),k=Math.min(g[d][b+"y"],k);return h=h||1,i=i||1,{weightMax:h,sizeMax:i,minX:j,minY:k,maxX:l,maxY:m}}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.middlewares"),sigma.middlewares.copy=function(a,b){var c,d,e;if(b+""!=a+""){for(e=this.graph.nodes(),c=0,d=e.length;d>c;c++)e[c][b+"x"]=e[c][a+"x"],e[c][b+"y"]=e[c][a+"y"],e[c][b+"size"]=e[c][a+"size"];for(e=this.graph.edges(),c=0,d=e.length;d>c;c++)e[c][b+"size"]=e[c][a+"size"]}}}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.misc.animation.running");var b=function(){var a=0;return function(){return""+ ++a}}();sigma.misc.animation.camera=function(c,d,e){if(!(c instanceof sigma.classes.camera&&"object"==typeof d&&d))throw"animation.camera: Wrong arguments.";if("number"!=typeof d.x&&"number"!=typeof d.y&&"number"!=typeof d.ratio&&"number"!=typeof d.angle)throw"There must be at least one valid coordinate in the given val.";var f,g,h,i,j,k,l=e||{},m=sigma.utils.dateNow();return k={x:c.x,y:c.y,ratio:c.ratio,angle:c.angle},j=l.duration,i="function"!=typeof l.easing?sigma.utils.easings[l.easing||"quadraticInOut"]:l.easing,f=function(){var b,e=l.duration?(sigma.utils.dateNow()-m)/l.duration:1;e>=1?(c.isAnimated=!1,c.goTo({x:d.x!==a?d.x:k.x,y:d.y!==a?d.y:k.y,ratio:d.ratio!==a?d.ratio:k.ratio,angle:d.angle!==a?d.angle:k.angle}),cancelAnimationFrame(g),delete sigma.misc.animation.running[g],"function"==typeof l.onComplete&&l.onComplete()):(b=i(e),c.isAnimated=!0,c.goTo({x:d.x!==a?k.x+(d.x-k.x)*b:k.x,y:d.y!==a?k.y+(d.y-k.y)*b:k.y,ratio:d.ratio!==a?k.ratio+(d.ratio-k.ratio)*b:k.ratio,angle:d.angle!==a?k.angle+(d.angle-k.angle)*b:k.angle}),"function"==typeof l.onNewFrame&&l.onNewFrame(),h.frameId=requestAnimationFrame(f))},g=b(),h={frameId:requestAnimationFrame(f),target:c,type:"camera",options:l,fn:f},sigma.misc.animation.running[g]=h,g},sigma.misc.animation.kill=function(a){if(1!==arguments.length||"number"!=typeof a)throw"animation.kill: Wrong arguments.";var b=sigma.misc.animation.running[a];return b&&(cancelAnimationFrame(a),delete sigma.misc.animation.running[b.frameId],"camera"===b.type&&(b.target.isAnimated=!1),"function"==typeof(b.options||{}).onComplete&&b.options.onComplete()),this},sigma.misc.animation.killAll=function(a){var b,c,d=0,e="string"==typeof a?a:null,f="object"==typeof a?a:null,g=sigma.misc.animation.running;for(c in g)e&&g[c].type!==e||f&&g[c].target!==f||(b=sigma.misc.animation.running[c],cancelAnimationFrame(b.frameId),delete sigma.misc.animation.running[c],"camera"===b.type&&(b.target.isAnimated=!1),d++,"function"==typeof(b.options||{}).onComplete&&b.options.onComplete());return d},sigma.misc.animation.has=function(a){var b,c="string"==typeof a?a:null,d="object"==typeof a?a:null,e=sigma.misc.animation.running;for(b in e)if(!(c&&e[b].type!==c||d&&e[b].target!==d))return!0;return!1}}.call(this),function(a){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.misc"),sigma.misc.bindEvents=function(b){function c(a){a&&(h="x"in a.data?a.data.x:h,i="y"in a.data?a.data.y:i);var c,d,e,f,g,k,l,m,n=[],o=h+j.width/2,p=i+j.height/2,q=j.camera.cameraPosition(h,i),r=j.camera.quadtree.point(q.x,q.y);if(r.length)for(c=0,e=r.length;e>c;c++)if(f=r[c],g=f[b+"x"],k=f[b+"y"],l=f[b+"size"],!f.hidden&&o>g-l&&g+l>o&&p>k-l&&k+l>p&&Math.sqrt(Math.pow(o-g,2)+Math.pow(p-k,2))<l){for(m=!1,d=0;d<n.length;d++)if(f.size>n[d].size){n.splice(d,0,f),m=!0;break}m||n.push(f)}return n}function d(c){function d(a,b){for(r=!1,g=0;g<a.length;g++)if(b.size>a[g].size){a.splice(g,0,b),r=!0;break}r||a.push(b)}if(!j.settings("enableEdgeHovering"))return[];var e=sigma.renderers.canvas&&j instanceof sigma.renderers.canvas;if(!e)throw new Error("The edge events feature is not compatible with the WebGL renderer");c&&(h="x"in c.data?c.data.x:h,i="y"in c.data?c.data.y:i);var f,g,k,l,m,n,o,p,q,r,s=j.settings("edgeHoverPrecision"),t={},u=[],v=h+j.width/2,w=i+j.height/2,x=j.camera.cameraPosition(h,i),y=[];if(e){var z=j.camera.quadtree.area(j.camera.getRectangle(j.width,j.height));for(l=z,f=0,k=l.length;k>f;f++)t[l[f].id]=l[f]}if(j.camera.edgequadtree!==a&&(y=j.camera.edgequadtree.point(x.x,x.y)),y.length)for(f=0,k=y.length;k>f;f++)m=y[f],o=j.graph.nodes(m.source),p=j.graph.nodes(m.target),n=m[b+"size"]||m["read_"+b+"size"],!m.hidden&&!o.hidden&&!p.hidden&&(!e||t[m.source]||t[m.target])&&sigma.utils.getDistance(o[b+"x"],o[b+"y"],v,w)>o[b+"size"]&&sigma.utils.getDistance(p[b+"x"],p[b+"y"],v,w)>p[b+"size"]&&("curve"==m.type||"curvedArrow"==m.type?o.id===p.id?(q=sigma.utils.getSelfLoopControlPoints(o[b+"x"],o[b+"y"],o[b+"size"]),sigma.utils.isPointOnBezierCurve(v,w,o[b+"x"],o[b+"y"],p[b+"x"],p[b+"y"],q.x1,q.y1,q.x2,q.y2,Math.max(n,s))&&d(u,m)):(q=sigma.utils.getQuadraticControlPoint(o[b+"x"],o[b+"y"],p[b+"x"],p[b+"y"]),sigma.utils.isPointOnQuadraticCurve(v,w,o[b+"x"],o[b+"y"],p[b+"x"],p[b+"y"],q.x,q.y,Math.max(n,s))&&d(u,m)):sigma.utils.isPointOnSegment(v,w,o[b+"x"],o[b+"y"],p[b+"x"],p[b+"y"],Math.max(n,s))&&d(u,m));return u}function e(a){function b(a){j.settings("eventsEnabled")&&(j.dispatchEvent("click",a.data),i=c(a),k=d(a),i.length?(j.dispatchEvent("clickNode",{node:i[0],captor:a.data}),j.dispatchEvent("clickNodes",{node:i,captor:a.data})):k.length?(j.dispatchEvent("clickEdge",{edge:k[0],captor:a.data}),j.dispatchEvent("clickEdges",{edge:k,captor:a.data})):j.dispatchEvent("clickStage",{captor:a.data}))}function e(a){j.settings("eventsEnabled")&&(j.dispatchEvent("doubleClick",a.data),i=c(a),k=d(a),i.length?(j.dispatchEvent("doubleClickNode",{node:i[0],captor:a.data}),j.dispatchEvent("doubleClickNodes",{node:i,captor:a.data})):k.length?(j.dispatchEvent("doubleClickEdge",{edge:k[0],captor:a.data}),j.dispatchEvent("doubleClickEdges",{edge:k,captor:a.data})):j.dispatchEvent("doubleClickStage",{captor:a.data}))}function f(a){j.settings("eventsEnabled")&&(j.dispatchEvent("rightClick",a.data),i=c(a),k=d(a),i.length?(j.dispatchEvent("rightClickNode",{node:i[0],captor:a.data}),j.dispatchEvent("rightClickNodes",{node:i,captor:a.data})):k.length?(j.dispatchEvent("rightClickEdge",{edge:k[0],captor:a.data}),j.dispatchEvent("rightClickEdges",{edge:k,captor:a.data})):j.dispatchEvent("rightClickStage",{captor:a.data}))}function g(a){if(j.settings("eventsEnabled")){var b,c,d,e,f=[],g=[];for(b in l)f.push(l[b]);for(l={},c=0,d=f.length;d>c;c++)j.dispatchEvent("outNode",{node:f[c],captor:a.data});for(f.length&&j.dispatchEvent("outNodes",{nodes:f,captor:a.data}),m={},c=0,e=g.length;e>c;c++)j.dispatchEvent("outEdge",{edge:g[c],captor:a.data});g.length&&j.dispatchEvent("outEdges",{edges:g,captor:a.data})}}function h(a){if(j.settings("eventsEnabled")){i=c(a),k=d(a);var b,e,f,g,h=[],n=[],o={},p=i.length,q=[],r=[],s={},t=k.length;for(b=0;p>b;b++)f=i[b],o[f.id]=f,l[f.id]||(n.push(f),l[f.id]=f);for(e in l)o[e]||(h.push(l[e]),delete l[e]);for(b=0,p=n.length;p>b;b++)j.dispatchEvent("overNode",{node:n[b],captor:a.data});for(b=0,p=h.length;p>b;b++)j.dispatchEvent("outNode",{node:h[b],captor:a.data});for(n.length&&j.dispatchEvent("overNodes",{nodes:n,captor:a.data}),h.length&&j.dispatchEvent("outNodes",{nodes:h,captor:a.data}),b=0;t>b;b++)g=k[b],s[g.id]=g,m[g.id]||(r.push(g),m[g.id]=g);for(e in m)s[e]||(q.push(m[e]),delete m[e]);for(b=0,t=r.length;t>b;b++)j.dispatchEvent("overEdge",{edge:r[b],captor:a.data});for(b=0,t=q.length;t>b;b++)j.dispatchEvent("outEdge",{edge:q[b],captor:a.data});r.length&&j.dispatchEvent("overEdges",{edges:r,captor:a.data}),q.length&&j.dispatchEvent("outEdges",{edges:q,captor:a.data})}}var i,k,l={},m={};a.bind("click",b),a.bind("mousedown",h),a.bind("mouseup",h),a.bind("mousemove",h),a.bind("mouseout",g),a.bind("doubleclick",e),a.bind("rightclick",f),j.bind("render",h)}var f,g,h,i,j=this;for(f=0,g=this.captors.length;g>f;f++)e(this.captors[f])}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.misc"),sigma.misc.bindDOMEvents=function(a){function b(a){this.attr=function(b){return a.getAttributeNS(null,b)},this.tag=a.tagName,this.class=this.attr("class"),this.id=this.attr("id"),this.isNode=function(){return!!~this.class.indexOf(g.settings("classPrefix")+"-node")},this.isEdge=function(){return!!~this.class.indexOf(g.settings("classPrefix")+"-edge")},this.isHover=function(){return!!~this.class.indexOf(g.settings("classPrefix")+"-hover")}}function c(a){if(g.settings("eventsEnabled")){g.dispatchEvent("click",a);var c=new b(a.target);c.isNode()?g.dispatchEvent("clickNode",{node:h.nodes(c.attr("data-node-id"))}):g.dispatchEvent("clickStage"),a.preventDefault(),a.stopPropagation()}}function d(a){if(g.settings("eventsEnabled")){g.dispatchEvent("doubleClick",a);var c=new b(a.target);c.isNode()?g.dispatchEvent("doubleClickNode",{node:h.nodes(c.attr("data-node-id"))}):g.dispatchEvent("doubleClickStage"),a.preventDefault(),a.stopPropagation()}}function e(a){var c=a.toElement||a.target;if(g.settings("eventsEnabled")&&c){var d=new b(c);if(d.isNode())g.dispatchEvent("overNode",{node:h.nodes(d.attr("data-node-id"))});else if(d.isEdge()){var e=h.edges(d.attr("data-edge-id"));g.dispatchEvent("overEdge",{edge:e,source:h.nodes(e.source),target:h.nodes(e.target)})}}}function f(a){var c=a.fromElement||a.originalTarget;if(g.settings("eventsEnabled")){var d=new b(c);if(d.isNode())g.dispatchEvent("outNode",{node:h.nodes(d.attr("data-node-id"))});else if(d.isEdge()){var e=h.edges(d.attr("data-edge-id"));g.dispatchEvent("outEdge",{edge:e,source:h.nodes(e.source),target:h.nodes(e.target)})}}}var g=this,h=this.graph;a.addEventListener("click",c,!1),sigma.utils.doubleClick(a,"click",d),a.addEventListener("touchstart",c,!1),sigma.utils.doubleClick(a,"touchstart",d),a.addEventListener("mouseover",e,!0),a.addEventListener("mouseout",f,!0)}}.call(this),function(){"use strict";if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.misc"),sigma.misc.drawHovers=function(a){function b(){var b,f,g,h,i,j=c.contexts.hover.canvas,k=c.settings("defaultNodeType"),l=c.settings("defaultEdgeType"),m=sigma.canvas.hovers,n=sigma.canvas.edgehovers,o=sigma.canvas.extremities,p=c.settings.embedObjects({prefix:a});if(c.contexts.hover.clearRect(0,0,j.width,j.height),p("enableHovering")&&p("singleHover")&&Object.keys(d).length&&(h=d[Object.keys(d)[0]],(m[h.type]||m[k]||m.def)(h,c.contexts.hover,p)),p("enableHovering")&&!p("singleHover"))for(b in d)(m[d[b].type]||m[k]||m.def)(d[b],c.contexts.hover,p);if(p("enableEdgeHovering")&&p("singleHover")&&Object.keys(e).length&&(i=e[Object.keys(e)[0]],f=c.graph.nodes(i.source),g=c.graph.nodes(i.target),i.hidden||((n[i.type]||n[l]||n.def)(i,f,g,c.contexts.hover,p),p("edgeHoverExtremities")?(o[i.type]||o.def)(i,f,g,c.contexts.hover,p):((sigma.canvas.nodes[f.type]||sigma.canvas.nodes.def)(f,c.contexts.hover,p),(sigma.canvas.nodes[g.type]||sigma.canvas.nodes.def)(g,c.contexts.hover,p)))),p("enableEdgeHovering")&&!p("singleHover"))for(b in e)i=e[b],f=c.graph.nodes(i.source),g=c.graph.nodes(i.target),i.hidden||((n[i.type]||n[l]||n.def)(i,f,g,c.contexts.hover,p),p("edgeHoverExtremities")?(o[i.type]||o.def)(i,f,g,c.contexts.hover,p):((sigma.canvas.nodes[f.type]||sigma.canvas.nodes.def)(f,c.contexts.hover,p),(sigma.canvas.nodes[g.type]||sigma.canvas.nodes.def)(g,c.contexts.hover,p)))}var c=this,d={},e={};this.bind("overNode",function(a){var c=a.data.node;c.hidden||(d[c.id]=c,b())}),this.bind("outNode",function(a){delete d[a.data.node.id],b()}),this.bind("overEdge",function(a){var c=a.data.edge;c.hidden||(e[c.id]=c,b())}),this.bind("outEdge",function(a){delete e[a.data.edge.id],b()}),this.bind("render",function(){b()})}}.call(this);
\ No newline at end of file
diff --git a/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.require.js b/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.require.js
new file mode 100644
index 0000000..08381e6
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/js/topo/sigma/sigma.require.js
@@ -0,0 +1,12224 @@
+;(function(undefined) {
+  'use strict';
+
+  var __instances = {};
+
+  /**
+   * This is the sigma instances constructor. One instance of sigma represent
+   * one graph. It is possible to represent this grapĥ with several renderers
+   * at the same time. By default, the default renderer (WebGL + Canvas
+   * polyfill) will be used as the only renderer, with the container specified
+   * in the configuration.
+   *
+   * @param  {?*}    conf The configuration of the instance. There are a lot of
+   *                      different recognized forms to instantiate sigma, check
+   *                      example files, documentation in this file and unit
+   *                      tests to know more.
+   * @return {sigma}      The fresh new sigma instance.
+   *
+   * Instanciating sigma:
+   * ********************
+   * If no parameter is given to the constructor, the instance will be created
+   * without any renderer or camera. It will just instantiate the graph, and
+   * other modules will have to be instantiated through the public methods,
+   * like "addRenderer" etc:
+   *
+   *  > s0 = new sigma();
+   *  > s0.addRenderer({
+   *  >   type: 'canvas',
+   *  >   container: 'my-container-id'
+   *  > });
+   *
+   * In most of the cases, sigma will simply be used with the default renderer.
+   * Then, since the only required parameter is the DOM container, there are
+   * some simpler way to call the constructor. The four following calls do the
+   * exact same things:
+   *
+   *  > s1 = new sigma('my-container-id');
+   *  > s2 = new sigma(document.getElementById('my-container-id'));
+   *  > s3 = new sigma({
+   *  >   container: document.getElementById('my-container-id')
+   *  > });
+   *  > s4 = new sigma({
+   *  >   renderers: [{
+   *  >     container: document.getElementById('my-container-id')
+   *  >   }]
+   *  > });
+   *
+   * Recognized parameters:
+   * **********************
+   * Here is the exhaustive list of every accepted parameters, when calling the
+   * constructor with to top level configuration object (fourth case in the
+   * previous examples):
+   *
+   *   {?string} id        The id of the instance. It will be generated
+   *                       automatically if not specified.
+   *   {?array}  renderers An array containing objects describing renderers.
+   *   {?object} graph     An object containing an array of nodes and an array
+   *                       of edges, to avoid having to add them by hand later.
+   *   {?object} settings  An object containing instance specific settings that
+   *                       will override the default ones defined in the object
+   *                       sigma.settings.
+   */
+  var sigma = function(conf) {
+    // Local variables:
+    // ****************
+    var i,
+        l,
+        a,
+        c,
+        o,
+        id;
+
+    sigma.classes.dispatcher.extend(this);
+
+    // Private attributes:
+    // *******************
+    var _self = this,
+        _conf = conf || {};
+
+    // Little shortcut:
+    // ****************
+    // The configuration is supposed to have a list of the configuration
+    // objects for each renderer.
+    //  - If there are no configuration at all, then nothing is done.
+    //  - If there are no renderer list, the given configuration object will be
+    //    considered as describing the first and only renderer.
+    //  - If there are no renderer list nor "container" object, it will be
+    //    considered as the container itself (a DOM element).
+    //  - If the argument passed to sigma() is a string, it will be considered
+    //    as the ID of the DOM container.
+    if (
+      typeof _conf === 'string' ||
+      _conf instanceof HTMLElement
+    )
+      _conf = {
+        renderers: [_conf]
+      };
+    else if (Object.prototype.toString.call(_conf) === '[object Array]')
+      _conf = {
+        renderers: _conf
+      };
+
+    // Also check "renderer" and "container" keys:
+    o = _conf.renderers || _conf.renderer || _conf.container;
+    if (!_conf.renderers || _conf.renderers.length === 0)
+      if (
+        typeof o === 'string' ||
+        o instanceof HTMLElement ||
+        (typeof o === 'object' && 'container' in o)
+      )
+        _conf.renderers = [o];
+
+    // Recense the instance:
+    if (_conf.id) {
+      if (__instances[_conf.id])
+        throw 'sigma: Instance "' + _conf.id + '" already exists.';
+      Object.defineProperty(this, 'id', {
+        value: _conf.id
+      });
+    } else {
+      id = 0;
+      while (__instances[id])
+        id++;
+      Object.defineProperty(this, 'id', {
+        value: '' + id
+      });
+    }
+    __instances[this.id] = this;
+
+    // Initialize settings function:
+    this.settings = new sigma.classes.configurable(
+      sigma.settings,
+      _conf.settings || {}
+    );
+
+    // Initialize locked attributes:
+    Object.defineProperty(this, 'graph', {
+      value: new sigma.classes.graph(this.settings),
+      configurable: true
+    });
+    Object.defineProperty(this, 'middlewares', {
+      value: [],
+      configurable: true
+    });
+    Object.defineProperty(this, 'cameras', {
+      value: {},
+      configurable: true
+    });
+    Object.defineProperty(this, 'renderers', {
+      value: {},
+      configurable: true
+    });
+    Object.defineProperty(this, 'renderersPerCamera', {
+      value: {},
+      configurable: true
+    });
+    Object.defineProperty(this, 'cameraFrames', {
+      value: {},
+      configurable: true
+    });
+    Object.defineProperty(this, 'camera', {
+      get: function() {
+        return this.cameras[0];
+      }
+    });
+    Object.defineProperty(this, 'events', {
+      value: [
+        'click',
+        'rightClick',
+        'clickStage',
+        'doubleClickStage',
+        'rightClickStage',
+        'clickNode',
+        'clickNodes',
+        'doubleClickNode',
+        'doubleClickNodes',
+        'rightClickNode',
+        'rightClickNodes',
+        'overNode',
+        'overNodes',
+        'outNode',
+        'outNodes',
+        'downNode',
+        'downNodes',
+        'upNode',
+        'upNodes'
+      ],
+      configurable: true
+    });
+
+    // Add a custom handler, to redispatch events from renderers:
+    this._handler = (function(e) {
+      var k,
+          data = {};
+
+      for (k in e.data)
+        data[k] = e.data[k];
+
+      data.renderer = e.target;
+      this.dispatchEvent(e.type, data);
+    }).bind(this);
+
+    // Initialize renderers:
+    a = _conf.renderers || [];
+    for (i = 0, l = a.length; i < l; i++)
+      this.addRenderer(a[i]);
+
+    // Initialize middlewares:
+    a = _conf.middlewares || [];
+    for (i = 0, l = a.length; i < l; i++)
+      this.middlewares.push(
+        typeof a[i] === 'string' ?
+          sigma.middlewares[a[i]] :
+          a[i]
+      );
+
+    // Check if there is already a graph to fill in:
+    if (typeof _conf.graph === 'object' && _conf.graph) {
+      this.graph.read(_conf.graph);
+
+      // If a graph is given to the to the instance, the "refresh" method is
+      // directly called:
+      this.refresh();
+    }
+
+    // Deal with resize:
+    window.addEventListener('resize', function() {
+      if (_self.settings)
+        _self.refresh();
+    });
+  };
+
+
+
+
+  /**
+   * This methods will instantiate and reference a new camera. If no id is
+   * specified, then an automatic id will be generated.
+   *
+   * @param  {?string}              id Eventually the camera id.
+   * @return {sigma.classes.camera}    The fresh new camera instance.
+   */
+  sigma.prototype.addCamera = function(id) {
+    var self = this,
+        camera;
+
+    if (!arguments.length) {
+      id = 0;
+      while (this.cameras['' + id])
+        id++;
+      id = '' + id;
+    }
+
+    if (this.cameras[id])
+      throw 'sigma.addCamera: The camera "' + id + '" already exists.';
+
+    camera = new sigma.classes.camera(id, this.graph, this.settings);
+    this.cameras[id] = camera;
+
+    // Add a quadtree to the camera:
+    camera.quadtree = new sigma.classes.quad();
+
+    // Add an edgequadtree to the camera:
+    if (sigma.classes.edgequad !== undefined) {
+      camera.edgequadtree = new sigma.classes.edgequad();
+    }
+
+    camera.bind('coordinatesUpdated', function(e) {
+      self.renderCamera(camera, camera.isAnimated);
+    });
+
+    this.renderersPerCamera[id] = [];
+
+    return camera;
+  };
+
+  /**
+   * This method kills a camera, and every renderer attached to it.
+   *
+   * @param  {string|camera} v The camera to kill or its ID.
+   * @return {sigma}           Returns the instance.
+   */
+  sigma.prototype.killCamera = function(v) {
+    v = typeof v === 'string' ? this.cameras[v] : v;
+
+    if (!v)
+      throw 'sigma.killCamera: The camera is undefined.';
+
+    var i,
+        l,
+        a = this.renderersPerCamera[v.id];
+
+    for (l = a.length, i = l - 1; i >= 0; i--)
+      this.killRenderer(a[i]);
+
+    delete this.renderersPerCamera[v.id];
+    delete this.cameraFrames[v.id];
+    delete this.cameras[v.id];
+
+    if (v.kill)
+      v.kill();
+
+    return this;
+  };
+
+  /**
+   * This methods will instantiate and reference a new renderer. The "type"
+   * argument can be the constructor or its name in the "sigma.renderers"
+   * package. If no type is specified, then "sigma.renderers.def" will be used.
+   * If no id is specified, then an automatic id will be generated.
+   *
+   * @param  {?object}  options Eventually some options to give to the renderer
+   *                            constructor.
+   * @return {renderer}         The fresh new renderer instance.
+   *
+   * Recognized parameters:
+   * **********************
+   * Here is the exhaustive list of every accepted parameters in the "options"
+   * object:
+   *
+   *   {?string}            id     Eventually the renderer id.
+   *   {?(function|string)} type   Eventually the renderer constructor or its
+   *                               name in the "sigma.renderers" package.
+   *   {?(camera|string)}   camera Eventually the renderer camera or its
+   *                               id.
+   */
+  sigma.prototype.addRenderer = function(options) {
+    var id,
+        fn,
+        camera,
+        renderer,
+        o = options || {};
+
+    // Polymorphism:
+    if (typeof o === 'string')
+      o = {
+        container: document.getElementById(o)
+      };
+    else if (o instanceof HTMLElement)
+      o = {
+        container: o
+      };
+
+    // If the container still is a string, we get it by id
+    if (typeof o.container === 'string')
+      o.container = document.getElementById(o.container);
+
+    // Reference the new renderer:
+    if (!('id' in o)) {
+      id = 0;
+      while (this.renderers['' + id])
+        id++;
+      id = '' + id;
+    } else
+      id = o.id;
+
+    if (this.renderers[id])
+      throw 'sigma.addRenderer: The renderer "' + id + '" already exists.';
+
+    // Find the good constructor:
+    fn = typeof o.type === 'function' ? o.type : sigma.renderers[o.type];
+    fn = fn || sigma.renderers.def;
+
+    // Find the good camera:
+    camera = 'camera' in o ?
+      (
+        o.camera instanceof sigma.classes.camera ?
+          o.camera :
+          this.cameras[o.camera] || this.addCamera(o.camera)
+      ) :
+      this.addCamera();
+
+    if (this.cameras[camera.id] !== camera)
+      throw 'sigma.addRenderer: The camera is not properly referenced.';
+
+    // Instantiate:
+    renderer = new fn(this.graph, camera, this.settings, o);
+    this.renderers[id] = renderer;
+    Object.defineProperty(renderer, 'id', {
+      value: id
+    });
+
+    // Bind events:
+    if (renderer.bind)
+      renderer.bind(
+        [
+          'click',
+          'rightClick',
+          'clickStage',
+          'doubleClickStage',
+          'rightClickStage',
+          'clickNode',
+          'clickNodes',
+          'clickEdge',
+          'clickEdges',
+          'doubleClickNode',
+          'doubleClickNodes',
+          'doubleClickEdge',
+          'doubleClickEdges',
+          'rightClickNode',
+          'rightClickNodes',
+          'rightClickEdge',
+          'rightClickEdges',
+          'overNode',
+          'overNodes',
+          'overEdge',
+          'overEdges',
+          'outNode',
+          'outNodes',
+          'outEdge',
+          'outEdges',
+          'downNode',
+          'downNodes',
+          'downEdge',
+          'downEdges',
+          'upNode',
+          'upNodes',
+          'upEdge',
+          'upEdges'
+        ],
+        this._handler
+      );
+
+    // Reference the renderer by its camera:
+    this.renderersPerCamera[camera.id].push(renderer);
+
+    return renderer;
+  };
+
+  /**
+   * This method kills a renderer.
+   *
+   * @param  {string|renderer} v The renderer to kill or its ID.
+   * @return {sigma}             Returns the instance.
+   */
+  sigma.prototype.killRenderer = function(v) {
+    v = typeof v === 'string' ? this.renderers[v] : v;
+
+    if (!v)
+      throw 'sigma.killRenderer: The renderer is undefined.';
+
+    var a = this.renderersPerCamera[v.camera.id],
+        i = a.indexOf(v);
+
+    if (i >= 0)
+      a.splice(i, 1);
+
+    if (v.kill)
+      v.kill();
+
+    delete this.renderers[v.id];
+
+    return this;
+  };
+
+
+
+
+  /**
+   * This method calls the "render" method of each renderer, with the same
+   * arguments than the "render" method, but will also check if the renderer
+   * has a "process" method, and call it if it exists.
+   *
+   * It is useful for quadtrees or WebGL processing, for instance.
+   *
+   * @param  {?object}  options Eventually some options to give to the refresh
+   *                            method.
+   * @return {sigma}            Returns the instance itself.
+   *
+   * Recognized parameters:
+   * **********************
+   * Here is the exhaustive list of every accepted parameters in the "options"
+   * object:
+   *
+   *   {?boolean} skipIndexation A flag specifying wether or not the refresh
+   *                             function should reindex the graph in the
+   *                             quadtrees or not (default: false).
+   */
+  sigma.prototype.refresh = function(options) {
+    var i,
+        l,
+        k,
+        a,
+        c,
+        bounds,
+        prefix = 0;
+
+    options = options || {};
+
+    // Call each middleware:
+    a = this.middlewares || [];
+    for (i = 0, l = a.length; i < l; i++)
+      a[i].call(
+        this,
+        (i === 0) ? '' : 'tmp' + prefix + ':',
+        (i === l - 1) ? 'ready:' : ('tmp' + (++prefix) + ':')
+      );
+
+    // Then, for each camera, call the "rescale" middleware, unless the
+    // settings specify not to:
+    for (k in this.cameras) {
+      c = this.cameras[k];
+      if (
+        c.settings('autoRescale') &&
+        this.renderersPerCamera[c.id] &&
+        this.renderersPerCamera[c.id].length
+      )
+        sigma.middlewares.rescale.call(
+          this,
+          a.length ? 'ready:' : '',
+          c.readPrefix,
+          {
+            width: this.renderersPerCamera[c.id][0].width,
+            height: this.renderersPerCamera[c.id][0].height
+          }
+        );
+      else
+        sigma.middlewares.copy.call(
+          this,
+          a.length ? 'ready:' : '',
+          c.readPrefix
+        );
+
+      if (!options.skipIndexation) {
+        // Find graph boundaries:
+        bounds = sigma.utils.getBoundaries(
+          this.graph,
+          c.readPrefix
+        );
+
+        // Refresh quadtree:
+        c.quadtree.index(this.graph.nodes(), {
+          prefix: c.readPrefix,
+          bounds: {
+            x: bounds.minX,
+            y: bounds.minY,
+            width: bounds.maxX - bounds.minX,
+            height: bounds.maxY - bounds.minY
+          }
+        });
+
+        // Refresh edgequadtree:
+        if (
+          c.edgequadtree !== undefined &&
+          c.settings('drawEdges') &&
+          c.settings('enableEdgeHovering')
+        ) {
+          c.edgequadtree.index(this.graph, {
+            prefix: c.readPrefix,
+            bounds: {
+              x: bounds.minX,
+              y: bounds.minY,
+              width: bounds.maxX - bounds.minX,
+              height: bounds.maxY - bounds.minY
+            }
+          });
+        }
+      }
+    }
+
+    // Call each renderer:
+    a = Object.keys(this.renderers);
+    for (i = 0, l = a.length; i < l; i++)
+      if (this.renderers[a[i]].process) {
+        if (this.settings('skipErrors'))
+          try {
+            this.renderers[a[i]].process();
+          } catch (e) {
+            console.log(
+              'Warning: The renderer "' + a[i] + '" crashed on ".process()"'
+            );
+          }
+        else
+          this.renderers[a[i]].process();
+      }
+
+    this.render();
+
+    return this;
+  };
+
+  /**
+   * This method calls the "render" method of each renderer.
+   *
+   * @return {sigma} Returns the instance itself.
+   */
+  sigma.prototype.render = function() {
+    var i,
+        l,
+        a,
+        prefix = 0;
+
+    // Call each renderer:
+    a = Object.keys(this.renderers);
+    for (i = 0, l = a.length; i < l; i++)
+      if (this.settings('skipErrors'))
+        try {
+          this.renderers[a[i]].render();
+        } catch (e) {
+          if (this.settings('verbose'))
+            console.log(
+              'Warning: The renderer "' + a[i] + '" crashed on ".render()"'
+            );
+        }
+      else
+        this.renderers[a[i]].render();
+
+    return this;
+  };
+
+  /**
+   * This method calls the "render" method of each renderer that is bound to
+   * the specified camera. To improve the performances, if this method is
+   * called too often, the number of effective renderings is limitated to one
+   * per frame, unless you are using the "force" flag.
+   *
+   * @param  {sigma.classes.camera} camera The camera to render.
+   * @param  {?boolean}             force  If true, will render the camera
+   *                                       directly.
+   * @return {sigma}                       Returns the instance itself.
+   */
+  sigma.prototype.renderCamera = function(camera, force) {
+    var i,
+        l,
+        a,
+        self = this;
+
+    if (force) {
+      a = this.renderersPerCamera[camera.id];
+      for (i = 0, l = a.length; i < l; i++)
+        if (this.settings('skipErrors'))
+          try {
+            a[i].render();
+          } catch (e) {
+            if (this.settings('verbose'))
+              console.log(
+                'Warning: The renderer "' + a[i].id + '" crashed on ".render()"'
+              );
+          }
+        else
+          a[i].render();
+    } else {
+      if (!this.cameraFrames[camera.id]) {
+        a = this.renderersPerCamera[camera.id];
+        for (i = 0, l = a.length; i < l; i++)
+          if (this.settings('skipErrors'))
+            try {
+              a[i].render();
+            } catch (e) {
+              if (this.settings('verbose'))
+                console.log(
+                  'Warning: The renderer "' +
+                    a[i].id +
+                    '" crashed on ".render()"'
+                );
+            }
+          else
+            a[i].render();
+
+        this.cameraFrames[camera.id] = requestAnimationFrame(function() {
+          delete self.cameraFrames[camera.id];
+        });
+      }
+    }
+
+    return this;
+  };
+
+  /**
+   * This method calls the "kill" method of each module and destroys any
+   * reference from the instance.
+   */
+  sigma.prototype.kill = function() {
+    var k;
+
+    // Dispatching event
+    this.dispatchEvent('kill');
+
+    // Kill graph:
+    this.graph.kill();
+
+    // Kill middlewares:
+    delete this.middlewares;
+
+    // Kill each renderer:
+    for (k in this.renderers)
+      this.killRenderer(this.renderers[k]);
+
+    // Kill each camera:
+    for (k in this.cameras)
+      this.killCamera(this.cameras[k]);
+
+    delete this.renderers;
+    delete this.cameras;
+
+    // Kill everything else:
+    for (k in this)
+      if (this.hasOwnProperty(k))
+        delete this[k];
+
+    delete __instances[this.id];
+  };
+
+
+
+
+  /**
+   * Returns a clone of the instances object or a specific running instance.
+   *
+   * @param  {?string} id Eventually an instance ID.
+   * @return {object}     The related instance or a clone of the instances
+   *                      object.
+   */
+  sigma.instances = function(id) {
+    return arguments.length ?
+      __instances[id] :
+      sigma.utils.extend({}, __instances);
+  };
+
+
+
+  /**
+   * The current version of sigma:
+   */
+  sigma.version = '1.1.0';
+
+
+
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof this.sigma !== 'undefined')
+    throw 'An object called sigma is already in the global scope.';
+
+  this.sigma = sigma;
+
+}).call(this);
+
+/**
+ * conrad.js is a tiny JavaScript jobs scheduler,
+ *
+ * Version: 0.1.0
+ * Sources: http://github.com/jacomyal/conrad.js
+ * Doc:     http://github.com/jacomyal/conrad.js#readme
+ *
+ * License:
+ * --------
+ * Copyright © 2013 Alexis Jacomy, Sciences-Po médialab
+ *
+ * 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) {
+  'use strict';
+
+  // Check that conrad.js has not been loaded yet:
+  if (global.conrad)
+    throw new Error('conrad already exists');
+
+
+  /**
+   * PRIVATE VARIABLES:
+   * ******************
+   */
+
+  /**
+   * A flag indicating whether conrad is running or not.
+   *
+   * @type {Number}
+   */
+  var _lastFrameTime;
+
+  /**
+   * A flag indicating whether conrad is running or not.
+   *
+   * @type {Boolean}
+   */
+  var _isRunning = false;
+
+  /**
+   * The hash of registered jobs. Each job must at least have a unique ID
+   * under the key "id" and a function under the key "job". This hash
+   * contains each running job and each waiting job.
+   *
+   * @type {Object}
+   */
+  var _jobs = {};
+
+  /**
+   * The hash of currently running jobs.
+   *
+   * @type {Object}
+   */
+  var _runningJobs = {};
+
+  /**
+   * The array of currently running jobs, sorted by priority.
+   *
+   * @type {Array}
+   */
+  var _sortedByPriorityJobs = [];
+
+  /**
+   * The array of currently waiting jobs.
+   *
+   * @type {Object}
+   */
+  var _waitingJobs = {};
+
+  /**
+   * The array of finished jobs. They are stored in an array, since two jobs
+   * with the same "id" can happen at two different times.
+   *
+   * @type {Array}
+   */
+  var _doneJobs = [];
+
+  /**
+   * A dirty flag to keep conrad from starting: Indeed, when addJob() is called
+   * with several jobs, conrad must be started only at the end. This flag keeps
+   * me from duplicating the code that effectively adds a job.
+   *
+   * @type {Boolean}
+   */
+  var _noStart = false;
+
+  /**
+   * An hash containing some global settings about how conrad.js should
+   * behave.
+   *
+   * @type {Object}
+   */
+  var _parameters = {
+    frameDuration: 20,
+    history: true
+  };
+
+  /**
+   * This object contains every handlers bound to conrad events. It does not
+   * requirea any DOM implementation, since the events are all JavaScript.
+   *
+   * @type {Object}
+   */
+  var _handlers = Object.create(null);
+
+
+  /**
+   * PRIVATE FUNCTIONS:
+   * ******************
+   */
+
+  /**
+   * Will execute the handler everytime that the indicated event (or the
+   * indicated events) will be triggered.
+   *
+   * @param  {string|array|object} events  The name of the event (or the events
+   *                                       separated by spaces).
+   * @param  {function(Object)}    handler The handler to bind.
+   * @return {Object}                      Returns conrad.
+   */
+  function _bind(events, handler) {
+    var i,
+        i_end,
+        event,
+        eArray;
+
+    if (!arguments.length)
+      return;
+    else if (
+      arguments.length === 1 &&
+      Object(arguments[0]) === arguments[0]
+    )
+      for (events in arguments[0])
+        _bind(events, arguments[0][events]);
+    else if (arguments.length > 1) {
+      eArray =
+        Array.isArray(events) ?
+          events :
+          events.split(/ /);
+
+      for (i = 0, i_end = eArray.length; i !== i_end; i += 1) {
+        event = eArray[i];
+
+        if (!_handlers[event])
+          _handlers[event] = [];
+
+        // Using an object instead of directly the handler will make possible
+        // later to add flags
+        _handlers[event].push({
+          handler: handler
+        });
+      }
+    }
+  }
+
+  /**
+   * Removes the handler from a specified event (or specified events).
+   *
+   * @param  {?string}           events  The name of the event (or the events
+   *                                     separated by spaces). If undefined,
+   *                                     then all handlers are removed.
+   * @param  {?function(Object)} handler The handler to unbind. If undefined,
+   *                                     each handler bound to the event or the
+   *                                     events will be removed.
+   * @return {Object}            Returns conrad.
+   */
+  function _unbind(events, handler) {
+    var i,
+        i_end,
+        j,
+        j_end,
+        a,
+        event,
+        eArray = Array.isArray(events) ?
+                   events :
+                   events.split(/ /);
+
+    if (!arguments.length)
+      _handlers = Object.create(null);
+    else if (handler) {
+      for (i = 0, i_end = eArray.length; i !== i_end; i += 1) {
+        event = eArray[i];
+        if (_handlers[event]) {
+          a = [];
+          for (j = 0, j_end = _handlers[event].length; j !== j_end; j += 1)
+            if (_handlers[event][j].handler !== handler)
+              a.push(_handlers[event][j]);
+
+          _handlers[event] = a;
+        }
+
+        if (_handlers[event] && _handlers[event].length === 0)
+          delete _handlers[event];
+      }
+    } else
+      for (i = 0, i_end = eArray.length; i !== i_end; i += 1)
+        delete _handlers[eArray[i]];
+  }
+
+  /**
+   * Executes each handler bound to the event.
+   *
+   * @param  {string}  events The name of the event (or the events separated
+   *                          by spaces).
+   * @param  {?Object} data   The content of the event (optional).
+   * @return {Object}         Returns conrad.
+   */
+  function _dispatch(events, data) {
+    var i,
+        j,
+        i_end,
+        j_end,
+        event,
+        eventName,
+        eArray = Array.isArray(events) ?
+                   events :
+                   events.split(/ /);
+
+    data = data === undefined ? {} : data;
+
+    for (i = 0, i_end = eArray.length; i !== i_end; i += 1) {
+      eventName = eArray[i];
+
+      if (_handlers[eventName]) {
+        event = {
+          type: eventName,
+          data: data || {}
+        };
+
+        for (j = 0, j_end = _handlers[eventName].length; j !== j_end; j += 1)
+          try {
+            _handlers[eventName][j].handler(event);
+          } catch (e) {}
+      }
+    }
+  }
+
+  /**
+   * Executes the most prioritary job once, and deals with filling the stats
+   * (done, time, averageTime, currentTime, etc...).
+   *
+   * @return {?Object} Returns the job object if it has to be killed, null else.
+   */
+  function _executeFirstJob() {
+    var i,
+        l,
+        test,
+        kill,
+        pushed = false,
+        time = __dateNow(),
+        job = _sortedByPriorityJobs.shift();
+
+    // Execute the job and look at the result:
+    test = job.job();
+
+    // Deal with stats:
+    time = __dateNow() - time;
+    job.done++;
+    job.time += time;
+    job.currentTime += time;
+    job.weightTime = job.currentTime / (job.weight || 1);
+    job.averageTime = job.time / job.done;
+
+    // Check if the job has to be killed:
+    kill = job.count ? (job.count <= job.done) : !test;
+
+    // Reset priorities:
+    if (!kill) {
+      for (i = 0, l = _sortedByPriorityJobs.length; i < l; i++)
+        if (_sortedByPriorityJobs[i].weightTime > job.weightTime) {
+          _sortedByPriorityJobs.splice(i, 0, job);
+          pushed = true;
+          break;
+        }
+
+      if (!pushed)
+        _sortedByPriorityJobs.push(job);
+    }
+
+    return kill ? job : null;
+  }
+
+  /**
+   * Activates a job, by adding it to the _runningJobs object and the
+   * _sortedByPriorityJobs array. It also initializes its currentTime value.
+   *
+   * @param  {Object} job The job to activate.
+   */
+  function _activateJob(job) {
+    var l = _sortedByPriorityJobs.length;
+
+    // Add the job to the running jobs:
+    _runningJobs[job.id] = job;
+    job.status = 'running';
+
+    // Add the job to the priorities:
+    if (l) {
+      job.weightTime = _sortedByPriorityJobs[l - 1].weightTime;
+      job.currentTime = job.weightTime * (job.weight || 1);
+    }
+
+    // Initialize the job and dispatch:
+    job.startTime = __dateNow();
+    _dispatch('jobStarted', __clone(job));
+
+    _sortedByPriorityJobs.push(job);
+  }
+
+  /**
+   * The main loop of conrad.js:
+   *  . It executes job such that they all occupate the same processing time.
+   *  . It stops jobs that do not need to be executed anymore.
+   *  . It triggers callbacks when it is relevant.
+   *  . It starts waiting jobs when they need to be started.
+   *  . It injects frames to keep a constant frapes per second ratio.
+   *  . It stops itself when there are no more jobs to execute.
+   */
+  function _loop() {
+    var k,
+        o,
+        l,
+        job,
+        time,
+        deadJob;
+
+    // Deal with the newly added jobs (the _jobs object):
+    for (k in _jobs) {
+      job = _jobs[k];
+
+      if (job.after)
+        _waitingJobs[k] = job;
+      else
+        _activateJob(job);
+
+      delete _jobs[k];
+    }
+
+    // Set the _isRunning flag to false if there are no running job:
+    _isRunning = !!_sortedByPriorityJobs.length;
+
+    // Deal with the running jobs (the _runningJobs object):
+    while (
+      _sortedByPriorityJobs.length &&
+      __dateNow() - _lastFrameTime < _parameters.frameDuration
+    ) {
+      deadJob = _executeFirstJob();
+
+      // Deal with the case where the job has ended:
+      if (deadJob) {
+        _killJob(deadJob.id);
+
+        // Check for waiting jobs:
+        for (k in _waitingJobs)
+          if (_waitingJobs[k].after === deadJob.id) {
+            _activateJob(_waitingJobs[k]);
+            delete _waitingJobs[k];
+          }
+      }
+    }
+
+    // Check if conrad still has jobs to deal with, and kill it if not:
+    if (_isRunning) {
+      // Update the _lastFrameTime:
+      _lastFrameTime = __dateNow();
+
+      _dispatch('enterFrame');
+      setTimeout(_loop, 0);
+    } else
+      _dispatch('stop');
+  }
+
+  /**
+   * Adds one or more jobs, and starts the loop if no job was running before. A
+   * job is at least a unique string "id" and a function, and there are some
+   * parameters that you can specify for each job to modify the way conrad will
+   * execute it. If a job is added with the "id" of another job that is waiting
+   * or still running, an error will be thrown.
+   *
+   * When a job is added, it is referenced in the _jobs object, by its id.
+   * Then, if it has to be executed right now, it will be also referenced in
+   * the _runningJobs object. If it has to wait, then it will be added into the
+   * _waitingJobs object, until it can start.
+   *
+   * Keep reading this documentation to see how to call this method.
+   *
+   * @return {Object} Returns conrad.
+   *
+   * Adding one job:
+   * ***************
+   * Basically, a job is defined by its string id and a function (the job). It
+   * is also possible to add some parameters:
+   *
+   *  > conrad.addJob('myJobId', myJobFunction);
+   *  > conrad.addJob('myJobId', {
+   *  >   job: myJobFunction,
+   *  >   someParameter: someValue
+   *  > });
+   *  > conrad.addJob({
+   *  >   id: 'myJobId',
+   *  >   job: myJobFunction,
+   *  >   someParameter: someValue
+   *  > });
+   *
+   * Adding several jobs:
+   * ********************
+   * When adding several jobs at the same time, it is possible to specify
+   * parameters for each one individually or for all:
+   *
+   *  > conrad.addJob([
+   *  >   {
+   *  >     id: 'myJobId1',
+   *  >     job: myJobFunction1,
+   *  >     someParameter1: someValue1
+   *  >   },
+   *  >   {
+   *  >     id: 'myJobId2',
+   *  >     job: myJobFunction2,
+   *  >     someParameter2: someValue2
+   *  >   }
+   *  > ], {
+   *  >   someCommonParameter: someCommonValue
+   *  > });
+   *  > conrad.addJob({
+   *  >   myJobId1: {,
+   *  >     job: myJobFunction1,
+   *  >     someParameter1: someValue1
+   *  >   },
+   *  >   myJobId2: {,
+   *  >     job: myJobFunction2,
+   *  >     someParameter2: someValue2
+   *  >   }
+   *  > }, {
+   *  >   someCommonParameter: someCommonValue
+   *  > });
+   *  > conrad.addJob({
+   *  >   myJobId1: myJobFunction1,
+   *  >   myJobId2: myJobFunction2
+   *  > }, {
+   *  >   someCommonParameter: someCommonValue
+   *  > });
+   *
+   *  Recognized parameters:
+   *  **********************
+   *  Here is the exhaustive list of every accepted parameters:
+   *
+   *    {?Function} end      A callback to execute when the job is ended. It is
+   *                         not executed if the job is killed instead of ended
+   *                         "naturally".
+   *    {?Integer}  count    The number of time the job has to be executed.
+   *    {?Number}   weight   If specified, the job will be executed as it was
+   *                         added "weight" times.
+   *    {?String}   after    The id of another job (eventually not added yet).
+   *                         If specified, this job will start only when the
+   *                         specified "after" job is ended.
+   */
+  function _addJob(v1, v2) {
+    var i,
+        l,
+        o;
+
+    // Array of jobs:
+    if (Array.isArray(v1)) {
+      // Keep conrad to start until the last job is added:
+      _noStart = true;
+
+      for (i = 0, l = v1.length; i < l; i++)
+        _addJob(v1[i].id, __extend(v1[i], v2));
+
+      _noStart = false;
+      if (!_isRunning) {
+        // Update the _lastFrameTime:
+        _lastFrameTime = __dateNow();
+
+        _dispatch('start');
+        _loop();
+      }
+    } else if (typeof v1 === 'object') {
+      // One job (object):
+      if (typeof v1.id === 'string')
+        _addJob(v1.id, v1);
+
+      // Hash of jobs:
+      else {
+        // Keep conrad to start until the last job is added:
+        _noStart = true;
+
+        for (i in v1)
+          if (typeof v1[i] === 'function')
+            _addJob(i, __extend({
+              job: v1[i]
+            }, v2));
+          else
+            _addJob(i, __extend(v1[i], v2));
+
+        _noStart = false;
+        if (!_isRunning) {
+          // Update the _lastFrameTime:
+          _lastFrameTime = __dateNow();
+
+          _dispatch('start');
+          _loop();
+        }
+      }
+
+    // One job (string, *):
+    } else if (typeof v1 === 'string') {
+      if (_hasJob(v1))
+        throw new Error(
+          '[conrad.addJob] Job with id "' + v1 + '" already exists.'
+        );
+
+      // One job (string, function):
+      if (typeof v2 === 'function') {
+        o = {
+          id: v1,
+          done: 0,
+          time: 0,
+          status: 'waiting',
+          currentTime: 0,
+          averageTime: 0,
+          weightTime: 0,
+          job: v2
+        };
+
+      // One job (string, object):
+      } else if (typeof v2 === 'object') {
+        o = __extend(
+          {
+            id: v1,
+            done: 0,
+            time: 0,
+            status: 'waiting',
+            currentTime: 0,
+            averageTime: 0,
+            weightTime: 0
+          },
+          v2
+        );
+
+      // If none of those cases, throw an error:
+      } else
+        throw new Error('[conrad.addJob] Wrong arguments.');
+
+      // Effectively add the job:
+      _jobs[v1] = o;
+      _dispatch('jobAdded', __clone(o));
+
+      // Check if the loop has to be started:
+      if (!_isRunning && !_noStart) {
+        // Update the _lastFrameTime:
+        _lastFrameTime = __dateNow();
+
+        _dispatch('start');
+        _loop();
+      }
+
+    // If none of those cases, throw an error:
+    } else
+      throw new Error('[conrad.addJob] Wrong arguments.');
+
+    return this;
+  }
+
+  /**
+   * Kills one or more jobs, indicated by their ids. It is only possible to
+   * kill running jobs or waiting jobs. If you try to kill a job that does not
+   * exist or that is already killed, a warning will be thrown.
+   *
+   * @param  {Array|String} v1 A string job id or an array of job ids.
+   * @return {Object}       Returns conrad.
+   */
+  function _killJob(v1) {
+    var i,
+        l,
+        k,
+        a,
+        job,
+        found = false;
+
+    // Array of job ids:
+    if (Array.isArray(v1))
+      for (i = 0, l = v1.length; i < l; i++)
+        _killJob(v1[i]);
+
+    // One job's id:
+    else if (typeof v1 === 'string') {
+      a = [_runningJobs, _waitingJobs, _jobs];
+
+      // Remove the job from the hashes:
+      for (i = 0, l = a.length; i < l; i++)
+        if (v1 in a[i]) {
+          job = a[i][v1];
+
+          if (_parameters.history) {
+            job.status = 'done';
+            _doneJobs.push(job);
+          }
+
+          _dispatch('jobEnded', __clone(job));
+          delete a[i][v1];
+
+          if (typeof job.end === 'function')
+            job.end();
+
+          found = true;
+        }
+
+      // Remove the priorities array:
+      a = _sortedByPriorityJobs;
+      for (i = 0, l = a.length; i < l; i++)
+        if (a[i].id === v1) {
+          a.splice(i, 1);
+          break;
+        }
+
+      if (!found)
+        throw new Error('[conrad.killJob] Job "' + v1 + '" not found.');
+
+    // If none of those cases, throw an error:
+    } else
+      throw new Error('[conrad.killJob] Wrong arguments.');
+
+    return this;
+  }
+
+  /**
+   * Kills every running, waiting, and just added jobs.
+   *
+   * @return {Object} Returns conrad.
+   */
+  function _killAll() {
+    var k,
+        jobs = __extend(_jobs, _runningJobs, _waitingJobs);
+
+    // Take every jobs and push them into the _doneJobs object:
+    if (_parameters.history)
+      for (k in jobs) {
+        jobs[k].status = 'done';
+        _doneJobs.push(jobs[k]);
+
+        if (typeof jobs[k].end === 'function')
+          jobs[k].end();
+      }
+
+    // Reinitialize the different jobs lists:
+    _jobs = {};
+    _waitingJobs = {};
+    _runningJobs = {};
+    _sortedByPriorityJobs = [];
+
+    // In case some jobs are added right after the kill:
+    _isRunning = false;
+
+    return this;
+  }
+
+  /**
+   * Returns true if a job with the specified id is currently running or
+   * waiting, and false else.
+   *
+   * @param  {String}  id The id of the job.
+   * @return {?Object} Returns the job object if it exists.
+   */
+  function _hasJob(id) {
+    var job = _jobs[id] || _runningJobs[id] || _waitingJobs[id];
+    return job ? __extend(job) : null;
+  }
+
+  /**
+   * This method will set the setting specified by "v1" to the value specified
+   * by "v2" if both are given, and else return the current value of the
+   * settings "v1".
+   *
+   * @param  {String}   v1 The name of the property.
+   * @param  {?*}       v2 Eventually, a value to set to the specified
+   *                       property.
+   * @return {Object|*} Returns the specified settings value if "v2" is not
+   *                    given, and conrad else.
+   */
+  function _settings(v1, v2) {
+    var o;
+
+    if (typeof a1 === 'string' && arguments.length === 1)
+      return _parameters[a1];
+    else {
+      o = (typeof a1 === 'object' && arguments.length === 1) ?
+        a1 || {} :
+        {};
+      if (typeof a1 === 'string')
+        o[a1] = a2;
+
+      for (var k in o)
+        if (o[k] !== undefined)
+          _parameters[k] = o[k];
+        else
+          delete _parameters[k];
+
+      return this;
+    }
+  }
+
+  /**
+   * Returns true if conrad is currently running, and false else.
+   *
+   * @return {Boolean} Returns _isRunning.
+   */
+  function _getIsRunning() {
+    return _isRunning;
+  }
+
+  /**
+   * Unreference every job that is stored in the _doneJobs object. It will
+   * not be possible anymore to get stats about these jobs, but it will release
+   * the memory.
+   *
+   * @return {Object} Returns conrad.
+   */
+  function _clearHistory() {
+    _doneJobs = [];
+    return this;
+  }
+
+  /**
+   * Returns a snapshot of every data about jobs that wait to be started, are
+   * currently running or are done.
+   *
+   * It is possible to get only running, waiting or done jobs by giving
+   * "running", "waiting" or "done" as fist argument.
+   *
+   * It is also possible to get every job with a specified id by giving it as
+   * first argument. Also, using a RegExp instead of an id will return every
+   * jobs whose ids match the RegExp. And these two last use cases work as well
+   * by giving before "running", "waiting" or "done".
+   *
+   * @return {Array} The array of the matching jobs.
+   *
+   * Some call examples:
+   * *******************
+   *  > conrad.getStats('running')
+   *  > conrad.getStats('waiting')
+   *  > conrad.getStats('done')
+   *  > conrad.getStats('myJob')
+   *  > conrad.getStats(/test/)
+   *  > conrad.getStats('running', 'myRunningJob')
+   *  > conrad.getStats('running', /test/)
+   */
+  function _getStats(v1, v2) {
+    var a,
+        k,
+        i,
+        l,
+        stats,
+        pattern,
+        isPatternString;
+
+    if (!arguments.length) {
+      stats = [];
+
+      for (k in _jobs)
+        stats.push(_jobs[k]);
+
+      for (k in _waitingJobs)
+        stats.push(_waitingJobs[k]);
+
+      for (k in _runningJobs)
+        stats.push(_runningJobs[k]);
+
+      stats = stats.concat(_doneJobs);
+    }
+
+    if (typeof v1 === 'string')
+      switch (v1) {
+        case 'waiting':
+          stats = __objectValues(_waitingJobs);
+          break;
+        case 'running':
+          stats = __objectValues(_runningJobs);
+          break;
+        case 'done':
+          stats = _doneJobs;
+          break;
+        default:
+          pattern = v1;
+      }
+
+    if (v1 instanceof RegExp)
+      pattern = v1;
+
+    if (!pattern && (typeof v2 === 'string' || v2 instanceof RegExp))
+      pattern = v2;
+
+    // Filter jobs if a pattern is given:
+    if (pattern) {
+      isPatternString = typeof pattern === 'string';
+
+      if (stats instanceof Array) {
+        a = stats;
+      } else if (typeof stats === 'object') {
+        a = [];
+
+        for (k in stats)
+          a = a.concat(stats[k]);
+      } else {
+        a = [];
+
+        for (k in _jobs)
+          a.push(_jobs[k]);
+
+        for (k in _waitingJobs)
+          a.push(_waitingJobs[k]);
+
+        for (k in _runningJobs)
+          a.push(_runningJobs[k]);
+
+        a = a.concat(_doneJobs);
+      }
+
+      stats = [];
+      for (i = 0, l = a.length; i < l; i++)
+        if (isPatternString ? a[i].id === pattern : a[i].id.match(pattern))
+          stats.push(a[i]);
+    }
+
+    return __clone(stats);
+  }
+
+
+  /**
+   * TOOLS FUNCTIONS:
+   * ****************
+   */
+
+  /**
+   * This function takes any number of objects as arguments, copies from each
+   * of these objects each pair key/value into a new object, and finally
+   * returns this object.
+   *
+   * The arguments are parsed from the last one to the first one, such that
+   * when two objects have keys in common, the "earliest" object wins.
+   *
+   * Example:
+   * ********
+   *  > var o1 = {
+   *  >       a: 1,
+   *  >       b: 2,
+   *  >       c: '3'
+   *  >     },
+   *  >     o2 = {
+   *  >       c: '4',
+   *  >       d: [ 5 ]
+   *  >     };
+   *  > __extend(o1, o2);
+   *  > // Returns: {
+   *  > //   a: 1,
+   *  > //   b: 2,
+   *  > //   c: '3',
+   *  > //   d: [ 5 ]
+   *  > // };
+   *
+   * @param  {Object+} Any number of objects.
+   * @return {Object}  The merged object.
+   */
+  function __extend() {
+    var i,
+        k,
+        res = {},
+        l = arguments.length;
+
+    for (i = l - 1; i >= 0; i--)
+      for (k in arguments[i])
+        res[k] = arguments[i][k];
+
+    return res;
+  }
+
+  /**
+   * This function simply clones an object. This object must contain only
+   * objects, arrays and immutable values. Since it is not public, it does not
+   * deal with cyclic references, DOM elements and instantiated objects - so
+   * use it carefully.
+   *
+   * @param  {Object} The object to clone.
+   * @return {Object} The clone.
+   */
+  function __clone(item) {
+    var result, i, k, l;
+
+    if (!item)
+      return item;
+
+    if (Array.isArray(item)) {
+      result = [];
+      for (i = 0, l = item.length; i < l; i++)
+        result.push(__clone(item[i]));
+    } else if (typeof item === 'object') {
+      result = {};
+      for (i in item)
+        result[i] = __clone(item[i]);
+    } else
+      result = item;
+
+    return result;
+  }
+
+  /**
+   * Returns an array containing the values of an object.
+   *
+   * @param  {Object} The object.
+   * @return {Array}  The array of values.
+   */
+  function __objectValues(o) {
+    var k,
+        a = [];
+
+    for (k in o)
+      a.push(o[k]);
+
+    return a;
+  }
+
+  /**
+   * A short "Date.now()" polyfill.
+   *
+   * @return {Number} The current time (in ms).
+   */
+  function __dateNow() {
+    return Date.now ? Date.now() : new Date().getTime();
+  }
+
+  /**
+   * Polyfill for the Array.isArray function:
+   */
+  if (!Array.isArray)
+    Array.isArray = function(v) {
+      return Object.prototype.toString.call(v) === '[object Array]';
+    };
+
+
+  /**
+   * EXPORT PUBLIC API:
+   * ******************
+   */
+  var conrad = {
+    hasJob: _hasJob,
+    addJob: _addJob,
+    killJob: _killJob,
+    killAll: _killAll,
+    settings: _settings,
+    getStats: _getStats,
+    isRunning: _getIsRunning,
+    clearHistory: _clearHistory,
+
+    // Events management:
+    bind: _bind,
+    unbind: _unbind,
+
+    // Version:
+    version: '0.1.0'
+  };
+
+  if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = conrad;
+    exports.conrad = conrad;
+  }
+  global.conrad = conrad;
+})(this);
+
+// Hardcoded export for the node.js version:
+var sigma = this.sigma,
+    conrad = this.conrad;
+
+sigma.conrad = conrad;
+
+// Dirty polyfills to permit sigma usage in node
+if (HTMLElement === undefined)
+  var HTMLElement = function() {};
+
+if (window === undefined)
+  var window = {
+    addEventListener: function() {}
+  };
+
+if (typeof exports !== 'undefined') {
+  if (typeof module !== 'undefined' && module.exports)
+    exports = module.exports = sigma;
+  exports.sigma = sigma;
+}
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  var _root = this;
+
+  // Initialize packages:
+  sigma.utils = sigma.utils || {};
+
+  /**
+   * MISC UTILS:
+   */
+  /**
+   * This function takes any number of objects as arguments, copies from each
+   * of these objects each pair key/value into a new object, and finally
+   * returns this object.
+   *
+   * The arguments are parsed from the last one to the first one, such that
+   * when several objects have keys in common, the "earliest" object wins.
+   *
+   * Example:
+   * ********
+   *  > var o1 = {
+   *  >       a: 1,
+   *  >       b: 2,
+   *  >       c: '3'
+   *  >     },
+   *  >     o2 = {
+   *  >       c: '4',
+   *  >       d: [ 5 ]
+   *  >     };
+   *  > sigma.utils.extend(o1, o2);
+   *  > // Returns: {
+   *  > //   a: 1,
+   *  > //   b: 2,
+   *  > //   c: '3',
+   *  > //   d: [ 5 ]
+   *  > // };
+   *
+   * @param  {object+} Any number of objects.
+   * @return {object}  The merged object.
+   */
+  sigma.utils.extend = function() {
+    var i,
+        k,
+        res = {},
+        l = arguments.length;
+
+    for (i = l - 1; i >= 0; i--)
+      for (k in arguments[i])
+        res[k] = arguments[i][k];
+
+    return res;
+  };
+
+  /**
+   * A short "Date.now()" polyfill.
+   *
+   * @return {Number} The current time (in ms).
+   */
+  sigma.utils.dateNow = function() {
+    return Date.now ? Date.now() : new Date().getTime();
+  };
+
+  /**
+   * Takes a package name as parameter and checks at each lebel if it exists,
+   * and if it does not, creates it.
+   *
+   * Example:
+   * ********
+   *  > sigma.utils.pkg('a.b.c');
+   *  > a.b.c;
+   *  > // Object {};
+   *  >
+   *  > sigma.utils.pkg('a.b.d');
+   *  > a.b;
+   *  > // Object { c: {}, d: {} };
+   *
+   * @param  {string} pkgName The name of the package to create/find.
+   * @return {object}         The related package.
+   */
+  sigma.utils.pkg = function(pkgName) {
+    return (pkgName || '').split('.').reduce(function(context, objName) {
+      return (objName in context) ?
+        context[objName] :
+        (context[objName] = {});
+    }, _root);
+  };
+
+  /**
+   * Returns a unique incremental number ID.
+   *
+   * Example:
+   * ********
+   *  > sigma.utils.id();
+   *  > // 1;
+   *  >
+   *  > sigma.utils.id();
+   *  > // 2;
+   *  >
+   *  > sigma.utils.id();
+   *  > // 3;
+   *
+   * @param  {string} pkgName The name of the package to create/find.
+   * @return {object}         The related package.
+   */
+  sigma.utils.id = (function() {
+    var i = 0;
+    return function() {
+      return ++i;
+    };
+  })();
+
+  /**
+   * This function takes an hexa color (for instance "#ffcc00" or "#fc0") or a
+   * rgb / rgba color (like "rgb(255,255,12)" or "rgba(255,255,12,1)") and
+   * returns an integer equal to "r * 255 * 255 + g * 255 + b", to gain some
+   * memory in the data given to WebGL shaders.
+   *
+   * Note that the function actually caches its results for better performance.
+   *
+   * @param  {string} val The hexa or rgba color.
+   * @return {number}     The number value.
+   */
+  var floatColorCache = {};
+
+  sigma.utils.floatColor = function(val) {
+
+    // Is the color already computed?
+    if (floatColorCache[val])
+      return floatColorCache[val];
+
+    var original = val,
+        r = 0,
+        g = 0,
+        b = 0;
+
+    if (val[0] === '#') {
+      val = val.slice(1);
+
+      if (val.length === 3) {
+        r = parseInt(val.charAt(0) + val.charAt(0), 16);
+        g = parseInt(val.charAt(1) + val.charAt(1), 16);
+        b = parseInt(val.charAt(2) + val.charAt(2), 16);
+      }
+      else {
+        r = parseInt(val.charAt(0) + val.charAt(1), 16);
+        g = parseInt(val.charAt(2) + val.charAt(3), 16);
+        b = parseInt(val.charAt(4) + val.charAt(5), 16);
+      }
+    } else if (val.match(/^ *rgba? *\(/)) {
+      val = val.match(
+        /^ *rgba? *\( *([0-9]*) *, *([0-9]*) *, *([0-9]*) *(,.*)?\) *$/
+      );
+      r = +val[1];
+      g = +val[2];
+      b = +val[3];
+    }
+
+    var color = (
+      r * 256 * 256 +
+      g * 256 +
+      b
+    );
+
+    // Caching the color
+    floatColorCache[original] = color;
+
+    return color;
+  };
+
+    /**
+   * Perform a zoom into a camera, with or without animation, to the
+   * coordinates indicated using a specified ratio.
+   *
+   * Recognized parameters:
+   * **********************
+   * Here is the exhaustive list of every accepted parameters in the animation
+   * object:
+   *
+   *   {?number} duration     An amount of time that means the duration of the
+   *                          animation. If this parameter doesn't exist the
+   *                          zoom will be performed without animation.
+   *   {?function} onComplete A function to perform it after the animation. It
+   *                          will be performed even if there is no duration.
+   *
+   * @param {camera}     The camera where perform the zoom.
+   * @param {x}          The X coordiantion where the zoom goes.
+   * @param {y}          The Y coordiantion where the zoom goes.
+   * @param {ratio}      The ratio to apply it to the current camera ratio.
+   * @param {?animation} A dictionary with options for a possible animation.
+   */
+  sigma.utils.zoomTo = function(camera, x, y, ratio, animation) {
+    var settings = camera.settings,
+        count,
+        newRatio,
+        animationSettings,
+        coordinates;
+
+    // Create the newRatio dealing with min / max:
+    newRatio = Math.max(
+      settings('zoomMin'),
+      Math.min(
+        settings('zoomMax'),
+        camera.ratio * ratio
+      )
+    );
+
+    // Check that the new ratio is different from the initial one:
+    if (newRatio !== camera.ratio) {
+      // Create the coordinates variable:
+      ratio = newRatio / camera.ratio;
+      coordinates = {
+        x: x * (1 - ratio) + camera.x,
+        y: y * (1 - ratio) + camera.y,
+        ratio: newRatio
+      };
+
+      if (animation && animation.duration) {
+        // Complete the animation setings:
+        count = sigma.misc.animation.killAll(camera);
+        animation = sigma.utils.extend(
+          animation,
+          {
+            easing: count ? 'quadraticOut' : 'quadraticInOut'
+          }
+        );
+
+        sigma.misc.animation.camera(camera, coordinates, animation);
+      } else {
+        camera.goTo(coordinates);
+        if (animation && animation.onComplete)
+          animation.onComplete();
+      }
+    }
+  };
+
+  /**
+   * Return the control point coordinates for a quadratic bezier curve.
+   *
+   * @param  {number} x1  The X coordinate of the start point.
+   * @param  {number} y1  The Y coordinate of the start point.
+   * @param  {number} x2  The X coordinate of the end point.
+   * @param  {number} y2  The Y coordinate of the end point.
+   * @return {x,y}        The control point coordinates.
+   */
+  sigma.utils.getQuadraticControlPoint = function(x1, y1, x2, y2) {
+    return {
+      x: (x1 + x2) / 2 + (y2 - y1) / 4,
+      y: (y1 + y2) / 2 + (x1 - x2) / 4
+    };
+  };
+
+  /**
+    * Compute the coordinates of the point positioned
+    * at length t in the quadratic bezier curve.
+    *
+    * @param  {number} t  In [0,1] the step percentage to reach
+    *                     the point in the curve from the context point.
+    * @param  {number} x1 The X coordinate of the context point.
+    * @param  {number} y1 The Y coordinate of the context point.
+    * @param  {number} x2 The X coordinate of the ending point.
+    * @param  {number} y2 The Y coordinate of the ending point.
+    * @param  {number} xi The X coordinate of the control point.
+    * @param  {number} yi The Y coordinate of the control point.
+    * @return {object}    {x,y}.
+  */
+  sigma.utils.getPointOnQuadraticCurve = function(t, x1, y1, x2, y2, xi, yi) {
+    // http://stackoverflow.com/a/5634528
+    return {
+      x: Math.pow(1 - t, 2) * x1 + 2 * (1 - t) * t * xi + Math.pow(t, 2) * x2,
+      y: Math.pow(1 - t, 2) * y1 + 2 * (1 - t) * t * yi + Math.pow(t, 2) * y2
+    };
+  };
+
+  /**
+    * Compute the coordinates of the point positioned
+    * at length t in the cubic bezier curve.
+    *
+    * @param  {number} t  In [0,1] the step percentage to reach
+    *                     the point in the curve from the context point.
+    * @param  {number} x1 The X coordinate of the context point.
+    * @param  {number} y1 The Y coordinate of the context point.
+    * @param  {number} x2 The X coordinate of the end point.
+    * @param  {number} y2 The Y coordinate of the end point.
+    * @param  {number} cx The X coordinate of the first control point.
+    * @param  {number} cy The Y coordinate of the first control point.
+    * @param  {number} dx The X coordinate of the second control point.
+    * @param  {number} dy The Y coordinate of the second control point.
+    * @return {object}    {x,y} The point at t.
+  */
+  sigma.utils.getPointOnBezierCurve =
+    function(t, x1, y1, x2, y2, cx, cy, dx, dy) {
+    // http://stackoverflow.com/a/15397596
+    // Blending functions:
+    var B0_t = Math.pow(1 - t, 3),
+        B1_t = 3 * t * Math.pow(1 - t, 2),
+        B2_t = 3 * Math.pow(t, 2) * (1 - t),
+        B3_t = Math.pow(t, 3);
+
+    return {
+      x: (B0_t * x1) + (B1_t * cx) + (B2_t * dx) + (B3_t * x2),
+      y: (B0_t * y1) + (B1_t * cy) + (B2_t * dy) + (B3_t * y2)
+    };
+  };
+
+  /**
+   * Return the coordinates of the two control points for a self loop (i.e.
+   * where the start point is also the end point) computed as a cubic bezier
+   * curve.
+   *
+   * @param  {number} x    The X coordinate of the node.
+   * @param  {number} y    The Y coordinate of the node.
+   * @param  {number} size The node size.
+   * @return {x1,y1,x2,y2} The coordinates of the two control points.
+   */
+  sigma.utils.getSelfLoopControlPoints = function(x , y, size) {
+    return {
+      x1: x - size * 7,
+      y1: y,
+      x2: x,
+      y2: y + size * 7
+    };
+  };
+
+  /**
+   * Return the euclidian distance between two points of a plane
+   * with an orthonormal basis.
+   *
+   * @param  {number} x1  The X coordinate of the first point.
+   * @param  {number} y1  The Y coordinate of the first point.
+   * @param  {number} x2  The X coordinate of the second point.
+   * @param  {number} y2  The Y coordinate of the second point.
+   * @return {number}     The euclidian distance.
+   */
+  sigma.utils.getDistance = function(x0, y0, x1, y1) {
+    return Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
+  };
+
+  /**
+   * Return the coordinates of the intersection points of two circles.
+   *
+   * @param  {number} x0  The X coordinate of center location of the first
+   *                      circle.
+   * @param  {number} y0  The Y coordinate of center location of the first
+   *                      circle.
+   * @param  {number} r0  The radius of the first circle.
+   * @param  {number} x1  The X coordinate of center location of the second
+   *                      circle.
+   * @param  {number} y1  The Y coordinate of center location of the second
+   *                      circle.
+   * @param  {number} r1  The radius of the second circle.
+   * @return {xi,yi}      The coordinates of the intersection points.
+   */
+  sigma.utils.getCircleIntersection = function(x0, y0, r0, x1, y1, r1) {
+    // http://stackoverflow.com/a/12219802
+    var a, dx, dy, d, h, rx, ry, x2, y2;
+
+    // dx and dy are the vertical and horizontal distances between the circle
+    // centers:
+    dx = x1 - x0;
+    dy = y1 - y0;
+
+    // Determine the straight-line distance between the centers:
+    d = Math.sqrt((dy * dy) + (dx * dx));
+
+    // Check for solvability:
+    if (d > (r0 + r1)) {
+        // No solution. circles do not intersect.
+        return false;
+    }
+    if (d < Math.abs(r0 - r1)) {
+        // No solution. one circle is contained in the other.
+        return false;
+    }
+
+    //'point 2' is the point where the line through the circle intersection
+    // points crosses the line between the circle centers.
+
+    // Determine the distance from point 0 to point 2:
+    a = ((r0 * r0) - (r1 * r1) + (d * d)) / (2.0 * d);
+
+    // Determine the coordinates of point 2:
+    x2 = x0 + (dx * a / d);
+    y2 = y0 + (dy * a / d);
+
+    // Determine the distance from point 2 to either of the intersection
+    // points:
+    h = Math.sqrt((r0 * r0) - (a * a));
+
+    // Determine the offsets of the intersection points from point 2:
+    rx = -dy * (h / d);
+    ry = dx * (h / d);
+
+    // Determine the absolute intersection points:
+    var xi = x2 + rx;
+    var xi_prime = x2 - rx;
+    var yi = y2 + ry;
+    var yi_prime = y2 - ry;
+
+    return {xi: xi, xi_prime: xi_prime, yi: yi, yi_prime: yi_prime};
+  };
+
+  /**
+    * Check if a point is on a line segment.
+    *
+    * @param  {number} x       The X coordinate of the point to check.
+    * @param  {number} y       The Y coordinate of the point to check.
+    * @param  {number} x1      The X coordinate of the line start point.
+    * @param  {number} y1      The Y coordinate of the line start point.
+    * @param  {number} x2      The X coordinate of the line end point.
+    * @param  {number} y2      The Y coordinate of the line end point.
+    * @param  {number} epsilon The precision (consider the line thickness).
+    * @return {boolean}        True if point is "close to" the line
+    *                          segment, false otherwise.
+  */
+  sigma.utils.isPointOnSegment = function(x, y, x1, y1, x2, y2, epsilon) {
+    // http://stackoverflow.com/a/328122
+    var crossProduct = Math.abs((y - y1) * (x2 - x1) - (x - x1) * (y2 - y1)),
+        d = sigma.utils.getDistance(x1, y1, x2, y2),
+        nCrossProduct = crossProduct / d; // normalized cross product
+
+    return (nCrossProduct < epsilon &&
+     Math.min(x1, x2) <= x && x <= Math.max(x1, x2) &&
+     Math.min(y1, y2) <= y && y <= Math.max(y1, y2));
+  };
+
+  /**
+    * Check if a point is on a quadratic bezier curve segment with a thickness.
+    *
+    * @param  {number} x       The X coordinate of the point to check.
+    * @param  {number} y       The Y coordinate of the point to check.
+    * @param  {number} x1      The X coordinate of the curve start point.
+    * @param  {number} y1      The Y coordinate of the curve start point.
+    * @param  {number} x2      The X coordinate of the curve end point.
+    * @param  {number} y2      The Y coordinate of the curve end point.
+    * @param  {number} cpx     The X coordinate of the curve control point.
+    * @param  {number} cpy     The Y coordinate of the curve control point.
+    * @param  {number} epsilon The precision (consider the line thickness).
+    * @return {boolean}        True if (x,y) is on the curve segment,
+    *                          false otherwise.
+  */
+  sigma.utils.isPointOnQuadraticCurve =
+    function(x, y, x1, y1, x2, y2, cpx, cpy, epsilon) {
+    // Fails if the point is too far from the extremities of the segment,
+    // preventing for more costly computation:
+    var dP1P2 = sigma.utils.getDistance(x1, y1, x2, y2);
+    if (Math.abs(x - x1) > dP1P2 || Math.abs(y - y1) > dP1P2) {
+      return false;
+    }
+
+    var dP1 = sigma.utils.getDistance(x, y, x1, y1),
+        dP2 = sigma.utils.getDistance(x, y, x2, y2),
+        t = 0.5,
+        r = (dP1 < dP2) ? -0.01 : 0.01,
+        rThreshold = 0.001,
+        i = 100,
+        pt = sigma.utils.getPointOnQuadraticCurve(t, x1, y1, x2, y2, cpx, cpy),
+        dt = sigma.utils.getDistance(x, y, pt.x, pt.y),
+        old_dt;
+
+    // This algorithm minimizes the distance from the point to the curve. It
+    // find the optimal t value where t=0 is the start point and t=1 is the end
+    // point of the curve, starting from t=0.5.
+    // It terminates because it runs a maximum of i interations.
+    while (i-- > 0 &&
+      t >= 0 && t <= 1 &&
+      (dt > epsilon) &&
+      (r > rThreshold || r < -rThreshold)) {
+      old_dt = dt;
+      pt = sigma.utils.getPointOnQuadraticCurve(t, x1, y1, x2, y2, cpx, cpy);
+      dt = sigma.utils.getDistance(x, y, pt.x, pt.y);
+
+      if (dt > old_dt) {
+        // not the right direction:
+        // halfstep in the opposite direction
+        r = -r / 2;
+        t += r;
+      }
+      else if (t + r < 0 || t + r > 1) {
+        // oops, we've gone too far:
+        // revert with a halfstep
+        r = r / 2;
+        dt = old_dt;
+      }
+      else {
+        // progress:
+        t += r;
+      }
+    }
+
+    return dt < epsilon;
+  };
+
+
+  /**
+    * Check if a point is on a cubic bezier curve segment with a thickness.
+    *
+    * @param  {number} x       The X coordinate of the point to check.
+    * @param  {number} y       The Y coordinate of the point to check.
+    * @param  {number} x1      The X coordinate of the curve start point.
+    * @param  {number} y1      The Y coordinate of the curve start point.
+    * @param  {number} x2      The X coordinate of the curve end point.
+    * @param  {number} y2      The Y coordinate of the curve end point.
+    * @param  {number} cpx1    The X coordinate of the 1st curve control point.
+    * @param  {number} cpy1    The Y coordinate of the 1st curve control point.
+    * @param  {number} cpx2    The X coordinate of the 2nd curve control point.
+    * @param  {number} cpy2    The Y coordinate of the 2nd curve control point.
+    * @param  {number} epsilon The precision (consider the line thickness).
+    * @return {boolean}        True if (x,y) is on the curve segment,
+    *                          false otherwise.
+  */
+  sigma.utils.isPointOnBezierCurve =
+    function(x, y, x1, y1, x2, y2, cpx1, cpy1, cpx2, cpy2, epsilon) {
+    // Fails if the point is too far from the extremities of the segment,
+    // preventing for more costly computation:
+    var dP1CP1 = sigma.utils.getDistance(x1, y1, cpx1, cpy1);
+    if (Math.abs(x - x1) > dP1CP1 || Math.abs(y - y1) > dP1CP1) {
+      return false;
+    }
+
+    var dP1 = sigma.utils.getDistance(x, y, x1, y1),
+        dP2 = sigma.utils.getDistance(x, y, x2, y2),
+        t = 0.5,
+        r = (dP1 < dP2) ? -0.01 : 0.01,
+        rThreshold = 0.001,
+        i = 100,
+        pt = sigma.utils.getPointOnBezierCurve(
+          t, x1, y1, x2, y2, cpx1, cpy1, cpx2, cpy2),
+        dt = sigma.utils.getDistance(x, y, pt.x, pt.y),
+        old_dt;
+
+    // This algorithm minimizes the distance from the point to the curve. It
+    // find the optimal t value where t=0 is the start point and t=1 is the end
+    // point of the curve, starting from t=0.5.
+    // It terminates because it runs a maximum of i interations.
+    while (i-- > 0 &&
+      t >= 0 && t <= 1 &&
+      (dt > epsilon) &&
+      (r > rThreshold || r < -rThreshold)) {
+      old_dt = dt;
+      pt = sigma.utils.getPointOnBezierCurve(
+        t, x1, y1, x2, y2, cpx1, cpy1, cpx2, cpy2);
+      dt = sigma.utils.getDistance(x, y, pt.x, pt.y);
+
+      if (dt > old_dt) {
+        // not the right direction:
+        // halfstep in the opposite direction
+        r = -r / 2;
+        t += r;
+      }
+      else if (t + r < 0 || t + r > 1) {
+        // oops, we've gone too far:
+        // revert with a halfstep
+        r = r / 2;
+        dt = old_dt;
+      }
+      else {
+        // progress:
+        t += r;
+      }
+    }
+
+    return dt < epsilon;
+  };
+
+
+  /**
+   * ************
+   * EVENTS UTILS:
+   * ************
+   */
+  /**
+   * Here are some useful functions to unify extraction of the information we
+   * need with mouse events and touch events, from different browsers:
+   */
+
+  /**
+   * Extract the local X position from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {number}   The local X value of the mouse.
+   */
+  sigma.utils.getX = function(e) {
+    return (
+      (e.offsetX !== undefined && e.offsetX) ||
+      (e.layerX !== undefined && e.layerX) ||
+      (e.clientX !== undefined && e.clientX)
+    );
+  };
+
+  /**
+   * Extract the local Y position from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {number}   The local Y value of the mouse.
+   */
+  sigma.utils.getY = function(e) {
+    return (
+      (e.offsetY !== undefined && e.offsetY) ||
+      (e.layerY !== undefined && e.layerY) ||
+      (e.clientY !== undefined && e.clientY)
+    );
+  };
+
+  /**
+   * The pixel ratio of the screen. Taking zoom into account
+   *
+   * @return {number}        Pixel ratio of the screen
+   */
+  sigma.utils.getPixelRatio = function() {
+    var ratio = 1;
+    if (window.screen.deviceXDPI !== undefined &&
+         window.screen.logicalXDPI !== undefined &&
+         window.screen.deviceXDPI > window.screen.logicalXDPI) {
+        ratio = window.screen.systemXDPI / window.screen.logicalXDPI;
+    }
+    else if (window.devicePixelRatio !== undefined) {
+        ratio = window.devicePixelRatio;
+    }
+    return ratio;
+  };
+
+  /**
+   * Extract the width from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {number}   The width of the event's target.
+   */
+  sigma.utils.getWidth = function(e) {
+    var w = (!e.target.ownerSVGElement) ?
+              e.target.width :
+              e.target.ownerSVGElement.width;
+
+    return (
+      (typeof w === 'number' && w) ||
+      (w !== undefined && w.baseVal !== undefined && w.baseVal.value)
+    );
+  };
+
+  /**
+   * Extract the center from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {object}   The center of the event's target.
+   */
+  sigma.utils.getCenter = function(e) {
+    var ratio = e.target.namespaceURI.indexOf('svg') !== -1 ? 1 :
+        sigma.utils.getPixelRatio();
+    return {
+      x: sigma.utils.getWidth(e) / (2 * ratio),
+      y: sigma.utils.getHeight(e) / (2 * ratio),
+    };
+  };
+
+  /**
+   * Convert mouse coords to sigma coords
+   *
+   * @param  {event}   e A mouse or touch event.
+   * @param  {number?} x The x coord to convert
+   * @param  {number?} x The y coord to convert
+   *
+   * @return {object}    The standardized event
+   */
+  sigma.utils.mouseCoords = function(e, x, y) {
+    x = x || sigma.utils.getX(e);
+    y = y || sigma.utils.getY(e);
+    return {
+        x: x - sigma.utils.getCenter(e).x,
+        y: y - sigma.utils.getCenter(e).y,
+        clientX: e.clientX,
+        clientY: e.clientY,
+        ctrlKey: e.ctrlKey,
+        metaKey: e.metaKey,
+        altKey: e.altKey,
+        shiftKey: e.shiftKey
+    };
+  };
+
+  /**
+   * Extract the height from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {number}   The height of the event's target.
+   */
+  sigma.utils.getHeight = function(e) {
+    var h = (!e.target.ownerSVGElement) ?
+              e.target.height :
+              e.target.ownerSVGElement.height;
+
+    return (
+      (typeof h === 'number' && h) ||
+      (h !== undefined && h.baseVal !== undefined && h.baseVal.value)
+    );
+  };
+
+  /**
+   * Extract the wheel delta from a mouse or touch event.
+   *
+   * @param  {event}  e A mouse or touch event.
+   * @return {number}   The wheel delta of the mouse.
+   */
+  sigma.utils.getDelta = function(e) {
+    return (
+      (e.wheelDelta !== undefined && e.wheelDelta) ||
+      (e.detail !== undefined && -e.detail)
+    );
+  };
+
+  /**
+   * Returns the offset of a DOM element.
+   *
+   * @param  {DOMElement} dom The element to retrieve the position.
+   * @return {object}         The offset of the DOM element (top, left).
+   */
+  sigma.utils.getOffset = function(dom) {
+    var left = 0,
+        top = 0;
+
+    while (dom) {
+      top = top + parseInt(dom.offsetTop);
+      left = left + parseInt(dom.offsetLeft);
+      dom = dom.offsetParent;
+    }
+
+    return {
+      top: top,
+      left: left
+    };
+  };
+
+  /**
+   * Simulates a "double click" event.
+   *
+   * @param  {HTMLElement} target   The event target.
+   * @param  {string}      type     The event type.
+   * @param  {function}    callback The callback to execute.
+   */
+  sigma.utils.doubleClick = function(target, type, callback) {
+    var clicks = 0,
+        self = this,
+        handlers;
+
+    target._doubleClickHandler = target._doubleClickHandler || {};
+    target._doubleClickHandler[type] = target._doubleClickHandler[type] || [];
+    handlers = target._doubleClickHandler[type];
+
+    handlers.push(function(e) {
+      clicks++;
+
+      if (clicks === 2) {
+        clicks = 0;
+        return callback(e);
+      } else if (clicks === 1) {
+        setTimeout(function() {
+          clicks = 0;
+        }, sigma.settings.doubleClickTimeout);
+      }
+    });
+
+    target.addEventListener(type, handlers[handlers.length - 1], false);
+  };
+
+  /**
+   * Unbind simulated "double click" events.
+   *
+   * @param  {HTMLElement} target   The event target.
+   * @param  {string}      type     The event type.
+   */
+  sigma.utils.unbindDoubleClick = function(target, type) {
+    var handler,
+        handlers = (target._doubleClickHandler || {})[type] || [];
+
+    while ((handler = handlers.pop())) {
+      target.removeEventListener(type, handler);
+    }
+
+    delete (target._doubleClickHandler || {})[type];
+  };
+
+
+
+
+  /**
+   * Here are just some of the most basic easing functions, used for the
+   * animated camera "goTo" calls.
+   *
+   * If you need some more easings functions, don't hesitate to add them to
+   * sigma.utils.easings. But I will not add some more here or merge PRs
+   * containing, because I do not want sigma sources full of overkill and never
+   * used stuff...
+   */
+  sigma.utils.easings = sigma.utils.easings || {};
+  sigma.utils.easings.linearNone = function(k) {
+    return k;
+  };
+  sigma.utils.easings.quadraticIn = function(k) {
+    return k * k;
+  };
+  sigma.utils.easings.quadraticOut = function(k) {
+    return k * (2 - k);
+  };
+  sigma.utils.easings.quadraticInOut = function(k) {
+    if ((k *= 2) < 1)
+      return 0.5 * k * k;
+    return - 0.5 * (--k * (k - 2) - 1);
+  };
+  sigma.utils.easings.cubicIn = function(k) {
+    return k * k * k;
+  };
+  sigma.utils.easings.cubicOut = function(k) {
+    return --k * k * k + 1;
+  };
+  sigma.utils.easings.cubicInOut = function(k) {
+    if ((k *= 2) < 1)
+      return 0.5 * k * k * k;
+    return 0.5 * ((k -= 2) * k * k + 2);
+  };
+
+
+
+
+  /**
+   * ************
+   * WEBGL UTILS:
+   * ************
+   */
+  /**
+   * Loads a WebGL shader and returns it.
+   *
+   * @param  {WebGLContext}           gl           The WebGLContext to use.
+   * @param  {string}                 shaderSource The shader source.
+   * @param  {number}                 shaderType   The type of shader.
+   * @param  {function(string): void} error        Callback for errors.
+   * @return {WebGLShader}                         The created shader.
+   */
+  sigma.utils.loadShader = function(gl, shaderSource, shaderType, error) {
+    var compiled,
+        shader = gl.createShader(shaderType);
+
+    // Load the shader source
+    gl.shaderSource(shader, shaderSource);
+
+    // Compile the shader
+    gl.compileShader(shader);
+
+    // Check the compile status
+    compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
+
+    // If something went wrong:
+    if (!compiled) {
+      if (error) {
+        error(
+          'Error compiling shader "' + shader + '":' +
+          gl.getShaderInfoLog(shader)
+        );
+      }
+
+      gl.deleteShader(shader);
+      return null;
+    }
+
+    return shader;
+  };
+
+  /**
+   * Creates a program, attaches shaders, binds attrib locations, links the
+   * program and calls useProgram.
+   *
+   * @param  {Array.<WebGLShader>}    shaders   The shaders to attach.
+   * @param  {Array.<string>}         attribs   The attribs names.
+   * @param  {Array.<number>}         locations The locations for the attribs.
+   * @param  {function(string): void} error     Callback for errors.
+   * @return {WebGLProgram}                     The created program.
+   */
+  sigma.utils.loadProgram = function(gl, shaders, attribs, loc, error) {
+    var i,
+        linked,
+        program = gl.createProgram();
+
+    for (i = 0; i < shaders.length; ++i)
+      gl.attachShader(program, shaders[i]);
+
+    if (attribs)
+      for (i = 0; i < attribs.length; ++i)
+        gl.bindAttribLocation(
+          program,
+          locations ? locations[i] : i,
+          opt_attribs[i]
+        );
+
+    gl.linkProgram(program);
+
+    // Check the link status
+    linked = gl.getProgramParameter(program, gl.LINK_STATUS);
+    if (!linked) {
+      if (error)
+        error('Error in program linking: ' + gl.getProgramInfoLog(program));
+
+      gl.deleteProgram(program);
+      return null;
+    }
+
+    return program;
+  };
+
+
+
+
+  /**
+   * *********
+   * MATRICES:
+   * *********
+   * The following utils are just here to help generating the transformation
+   * matrices for the WebGL renderers.
+   */
+  sigma.utils.pkg('sigma.utils.matrices');
+
+  /**
+   * The returns a 3x3 translation matrix.
+   *
+   * @param  {number} dx The X translation.
+   * @param  {number} dy The Y translation.
+   * @return {array}     Returns the matrix.
+   */
+  sigma.utils.matrices.translation = function(dx, dy) {
+    return [
+      1, 0, 0,
+      0, 1, 0,
+      dx, dy, 1
+    ];
+  };
+
+  /**
+   * The returns a 3x3 or 2x2 rotation matrix.
+   *
+   * @param  {number}  angle The rotation angle.
+   * @param  {boolean} m2    If true, the function will return a 2x2 matrix.
+   * @return {array}         Returns the matrix.
+   */
+  sigma.utils.matrices.rotation = function(angle, m2) {
+    var cos = Math.cos(angle),
+        sin = Math.sin(angle);
+
+    return m2 ? [
+      cos, -sin,
+      sin, cos
+    ] : [
+      cos, -sin, 0,
+      sin, cos, 0,
+      0, 0, 1
+    ];
+  };
+
+  /**
+   * The returns a 3x3 or 2x2 homothetic transformation matrix.
+   *
+   * @param  {number}  ratio The scaling ratio.
+   * @param  {boolean} m2    If true, the function will return a 2x2 matrix.
+   * @return {array}         Returns the matrix.
+   */
+  sigma.utils.matrices.scale = function(ratio, m2) {
+    return m2 ? [
+      ratio, 0,
+      0, ratio
+    ] : [
+      ratio, 0, 0,
+      0, ratio, 0,
+      0, 0, 1
+    ];
+  };
+
+  /**
+   * The returns a 3x3 or 2x2 homothetic transformation matrix.
+   *
+   * @param  {array}   a  The first matrix.
+   * @param  {array}   b  The second matrix.
+   * @param  {boolean} m2 If true, the function will assume both matrices are
+   *                      2x2.
+   * @return {array}      Returns the matrix.
+   */
+  sigma.utils.matrices.multiply = function(a, b, m2) {
+    var l = m2 ? 2 : 3,
+        a00 = a[0 * l + 0],
+        a01 = a[0 * l + 1],
+        a02 = a[0 * l + 2],
+        a10 = a[1 * l + 0],
+        a11 = a[1 * l + 1],
+        a12 = a[1 * l + 2],
+        a20 = a[2 * l + 0],
+        a21 = a[2 * l + 1],
+        a22 = a[2 * l + 2],
+        b00 = b[0 * l + 0],
+        b01 = b[0 * l + 1],
+        b02 = b[0 * l + 2],
+        b10 = b[1 * l + 0],
+        b11 = b[1 * l + 1],
+        b12 = b[1 * l + 2],
+        b20 = b[2 * l + 0],
+        b21 = b[2 * l + 1],
+        b22 = b[2 * l + 2];
+
+    return m2 ? [
+      a00 * b00 + a01 * b10,
+      a00 * b01 + a01 * b11,
+      a10 * b00 + a11 * b10,
+      a10 * b01 + a11 * b11
+    ] : [
+      a00 * b00 + a01 * b10 + a02 * b20,
+      a00 * b01 + a01 * b11 + a02 * b21,
+      a00 * b02 + a01 * b12 + a02 * b22,
+      a10 * b00 + a11 * b10 + a12 * b20,
+      a10 * b01 + a11 * b11 + a12 * b21,
+      a10 * b02 + a11 * b12 + a12 * b22,
+      a20 * b00 + a21 * b10 + a22 * b20,
+      a20 * b01 + a21 * b11 + a22 * b21,
+      a20 * b02 + a21 * b12 + a22 * b22
+    ];
+  };
+}).call(this);
+
+;(function(global) {
+  'use strict';
+
+  /**
+   * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+   * http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
+   * requestAnimationFrame polyfill by Erik Möller.
+   * fixes from Paul Irish and Tino Zijdel
+   * MIT license
+   */
+  var x,
+      lastTime = 0,
+      vendors = ['ms', 'moz', 'webkit', 'o'];
+
+  for (x = 0; x < vendors.length && !global.requestAnimationFrame; x++) {
+    global.requestAnimationFrame =
+      global[vendors[x] + 'RequestAnimationFrame'];
+    global.cancelAnimationFrame =
+      global[vendors[x] + 'CancelAnimationFrame'] ||
+      global[vendors[x] + 'CancelRequestAnimationFrame'];
+  }
+
+  if (!global.requestAnimationFrame)
+    global.requestAnimationFrame = function(callback, element) {
+      var currTime = new Date().getTime(),
+          timeToCall = Math.max(0, 16 - (currTime - lastTime)),
+          id = global.setTimeout(
+            function() {
+              callback(currTime + timeToCall);
+            },
+            timeToCall
+          );
+
+      lastTime = currTime + timeToCall;
+      return id;
+    };
+
+  if (!global.cancelAnimationFrame)
+    global.cancelAnimationFrame = function(id) {
+      clearTimeout(id);
+    };
+
+  /**
+   * Function.prototype.bind polyfill found on MDN.
+   * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Compatibility
+   * Public domain
+   */
+  if (!Function.prototype.bind)
+    Function.prototype.bind = function(oThis) {
+      if (typeof this !== 'function')
+        // Closest thing possible to the ECMAScript 5 internal IsCallable
+        // function:
+        throw new TypeError(
+          'Function.prototype.bind - what is trying to be bound is not callable'
+        );
+
+      var aArgs = Array.prototype.slice.call(arguments, 1),
+          fToBind = this,
+          fNOP,
+          fBound;
+
+      fNOP = function() {};
+      fBound = function() {
+        return fToBind.apply(
+          this instanceof fNOP && oThis ?
+            this :
+            oThis,
+          aArgs.concat(Array.prototype.slice.call(arguments))
+        );
+      };
+
+      fNOP.prototype = this.prototype;
+      fBound.prototype = new fNOP();
+
+      return fBound;
+    };
+})(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Packages initialization:
+  sigma.utils.pkg('sigma.settings');
+
+  var settings = {
+    /**
+     * GRAPH SETTINGS:
+     * ***************
+     */
+    // {boolean} Indicates if the data have to be cloned in methods to add
+    //           nodes or edges.
+    clone: true,
+    // {boolean} Indicates if nodes "id" values and edges "id", "source" and
+    //           "target" values must be set as immutable.
+    immutable: true,
+    // {boolean} Indicates if sigma can log its errors and warnings.
+    verbose: false,
+
+
+    /**
+     * RENDERERS SETTINGS:
+     * *******************
+     */
+    // {string}
+    classPrefix: 'sigma',
+    // {string}
+    defaultNodeType: 'def',
+    // {string}
+    defaultEdgeType: 'def',
+    // {string}
+    defaultLabelColor: '#000',
+    // {string}
+    defaultEdgeColor: '#000',
+    // {string}
+    defaultNodeColor: '#000',
+    // {string}
+    defaultLabelSize: 14,
+    // {string} Indicates how to choose the edges color. Available values:
+    //          "source", "target", "default"
+    edgeColor: 'source',
+    // {number} Defines the minimal edge's arrow display size.
+    minArrowSize: 0,
+    // {string}
+    font: 'arial',
+    // {string} Example: 'bold'
+    fontStyle: '',
+    // {string} Indicates how to choose the labels color. Available values:
+    //          "node", "default"
+    labelColor: 'default',
+    // {string} Indicates how to choose the labels size. Available values:
+    //          "fixed", "proportional"
+    labelSize: 'fixed',
+    // {string} The ratio between the font size of the label and the node size.
+    labelSizeRatio: 1,
+    // {number} The minimum size a node must have to see its label displayed.
+    labelThreshold: 8,
+    // {number} The oversampling factor used in WebGL renderer.
+    webglOversamplingRatio: 2,
+    // {number} The size of the border of hovered nodes.
+    borderSize: 0,
+    // {number} The default hovered node border's color.
+    defaultNodeBorderColor: '#000',
+    // {number} The hovered node's label font. If not specified, will heritate
+    //          the "font" value.
+    hoverFont: '',
+    // {boolean} If true, then only one node can be hovered at a time.
+    singleHover: true,
+    // {string} Example: 'bold'
+    hoverFontStyle: '',
+    // {string} Indicates how to choose the hovered nodes shadow color.
+    //          Available values: "node", "default"
+    labelHoverShadow: 'default',
+    // {string}
+    labelHoverShadowColor: '#000',
+    // {string} Indicates how to choose the hovered nodes color.
+    //          Available values: "node", "default"
+    nodeHoverColor: 'node',
+    // {string}
+    defaultNodeHoverColor: '#000',
+    // {string} Indicates how to choose the hovered nodes background color.
+    //          Available values: "node", "default"
+    labelHoverBGColor: 'default',
+    // {string}
+    defaultHoverLabelBGColor: '#fff',
+    // {string} Indicates how to choose the hovered labels color.
+    //          Available values: "node", "default"
+    labelHoverColor: 'default',
+    // {string}
+    defaultLabelHoverColor: '#000',
+    // {string} Indicates how to choose the edges hover color. Available values:
+    //          "edge", "default"
+    edgeHoverColor: 'edge',
+    // {number} The size multiplicator of hovered edges.
+    edgeHoverSizeRatio: 1,
+    // {string}
+    defaultEdgeHoverColor: '#000',
+    // {boolean} Indicates if the edge extremities must be hovered when the
+    //           edge is hovered.
+    edgeHoverExtremities: false,
+    // {booleans} The different drawing modes:
+    //           false: Layered not displayed.
+    //           true: Layered displayed.
+    drawEdges: true,
+    drawNodes: true,
+    drawLabels: true,
+    drawEdgeLabels: false,
+    // {boolean} Indicates if the edges must be drawn in several frames or in
+    //           one frame, as the nodes and labels are drawn.
+    batchEdgesDrawing: false,
+    // {boolean} Indicates if the edges must be hidden during dragging and
+    //           animations.
+    hideEdgesOnMove: false,
+    // {numbers} The different batch sizes, when elements are displayed in
+    //           several frames.
+    canvasEdgesBatchSize: 500,
+    webglEdgesBatchSize: 1000,
+
+
+
+
+    /**
+     * RESCALE SETTINGS:
+     * *****************
+     */
+    // {string} Indicates of to scale the graph relatively to its container.
+    //          Available values: "inside", "outside"
+    scalingMode: 'inside',
+    // {number} The margin to keep around the graph.
+    sideMargin: 0,
+    // {number} Determine the size of the smallest and the biggest node / edges
+    //          on the screen. This mapping makes easier to display the graph,
+    //          avoiding too big nodes that take half of the screen, or too
+    //          small ones that are not readable. If the two parameters are
+    //          equals, then the minimal display size will be 0. And if they
+    //          are both equal to 0, then there is no mapping, and the radius
+    //          of the nodes will be their size.
+    minEdgeSize: 0.5,
+    maxEdgeSize: 1,
+    minNodeSize: 1,
+    maxNodeSize: 8,
+
+
+
+
+    /**
+     * CAPTORS SETTINGS:
+     * *****************
+     */
+    // {boolean}
+    touchEnabled: true,
+    // {boolean}
+    mouseEnabled: true,
+    // {boolean}
+    mouseWheelEnabled: true,
+    // {boolean}
+    doubleClickEnabled: true,
+    // {boolean} Defines whether the custom events such as "clickNode" can be
+    //           used.
+    eventsEnabled: true,
+    // {number} Defines by how much multiplicating the zooming level when the
+    //          user zooms with the mouse-wheel.
+    zoomingRatio: 1.7,
+    // {number} Defines by how much multiplicating the zooming level when the
+    //          user zooms by double clicking.
+    doubleClickZoomingRatio: 2.2,
+    // {number} The minimum zooming level.
+    zoomMin: 0.0625,
+    // {number} The maximum zooming level.
+    zoomMax: 2,
+    // {number} The duration of animations following a mouse scrolling.
+    mouseZoomDuration: 200,
+    // {number} The duration of animations following a mouse double click.
+    doubleClickZoomDuration: 200,
+    // {number} The duration of animations following a mouse dropping.
+    mouseInertiaDuration: 200,
+    // {number} The inertia power (mouse captor).
+    mouseInertiaRatio: 3,
+    // {number} The duration of animations following a touch dropping.
+    touchInertiaDuration: 200,
+    // {number} The inertia power (touch captor).
+    touchInertiaRatio: 3,
+    // {number} The maximum time between two clicks to make it a double click.
+    doubleClickTimeout: 300,
+    // {number} The maximum time between two taps to make it a double tap.
+    doubleTapTimeout: 300,
+    // {number} The maximum time of dragging to trigger intertia.
+    dragTimeout: 200,
+
+
+
+
+    /**
+     * GLOBAL SETTINGS:
+     * ****************
+     */
+    // {boolean} Determines whether the instance has to refresh itself
+    //           automatically when a "resize" event is dispatched from the
+    //           window object.
+    autoResize: true,
+    // {boolean} Determines whether the "rescale" middleware has to be called
+    //           automatically for each camera on refresh.
+    autoRescale: true,
+    // {boolean} If set to false, the camera method "goTo" will basically do
+    //           nothing.
+    enableCamera: true,
+    // {boolean} If set to false, the nodes cannot be hovered.
+    enableHovering: true,
+    // {boolean} If set to true, the edges can be hovered.
+    enableEdgeHovering: false,
+    // {number} The size of the area around the edges to activate hovering.
+    edgeHoverPrecision: 5,
+    // {boolean} If set to true, the rescale middleware will ignore node sizes
+    //           to determine the graphs boundings.
+    rescaleIgnoreSize: false,
+    // {boolean} Determines if the core has to try to catch errors on
+    //           rendering.
+    skipErrors: false,
+
+
+
+
+    /**
+     * CAMERA SETTINGS:
+     * ****************
+     */
+    // {number} The power degrees applied to the nodes/edges size relatively to
+    //          the zooming level. Basically:
+    //           > onScreenR = Math.pow(zoom, nodesPowRatio) * R
+    //           > onScreenT = Math.pow(zoom, edgesPowRatio) * T
+    nodesPowRatio: 0.5,
+    edgesPowRatio: 0.5,
+
+
+
+
+    /**
+     * ANIMATIONS SETTINGS:
+     * ********************
+     */
+    // {number} The default animation time.
+    animationsTime: 200
+  };
+
+  // Export the previously designed settings:
+  sigma.settings = sigma.utils.extend(sigma.settings || {}, settings);
+}).call(this);
+
+;(function() {
+  'use strict';
+
+  /**
+   * Dispatcher constructor.
+   *
+   * @return {dispatcher} The new dispatcher instance.
+   */
+  var dispatcher = function() {
+    Object.defineProperty(this, '_handlers', {
+      value: {}
+    });
+  };
+
+
+
+
+  /**
+   * Will execute the handler everytime that the indicated event (or the
+   * indicated events) will be triggered.
+   *
+   * @param  {string}           events  The name of the event (or the events
+   *                                    separated by spaces).
+   * @param  {function(Object)} handler The handler to bind.
+   * @return {dispatcher}               Returns the instance itself.
+   */
+  dispatcher.prototype.bind = function(events, handler) {
+    var i,
+        l,
+        event,
+        eArray;
+
+    if (
+      arguments.length === 1 &&
+      typeof arguments[0] === 'object'
+    )
+      for (events in arguments[0])
+        this.bind(events, arguments[0][events]);
+    else if (
+      arguments.length === 2 &&
+      typeof arguments[1] === 'function'
+    ) {
+      eArray = typeof events === 'string' ? events.split(' ') : events;
+
+      for (i = 0, l = eArray.length; i !== l; i += 1) {
+        event = eArray[i];
+
+        // Check that event is not '':
+        if (!event)
+          continue;
+
+        if (!this._handlers[event])
+          this._handlers[event] = [];
+
+        // Using an object instead of directly the handler will make possible
+        // later to add flags
+        this._handlers[event].push({
+          handler: handler
+        });
+      }
+    } else
+      throw 'bind: Wrong arguments.';
+
+    return this;
+  };
+
+  /**
+   * Removes the handler from a specified event (or specified events).
+   *
+   * @param  {?string}           events  The name of the event (or the events
+   *                                     separated by spaces). If undefined,
+   *                                     then all handlers are removed.
+   * @param  {?function(object)} handler The handler to unbind. If undefined,
+   *                                     each handler bound to the event or the
+   *                                     events will be removed.
+   * @return {dispatcher}                Returns the instance itself.
+   */
+  dispatcher.prototype.unbind = function(events, handler) {
+    var i,
+        n,
+        j,
+        m,
+        k,
+        a,
+        event,
+        eArray = typeof events === 'string' ? events.split(' ') : events;
+
+    if (!arguments.length) {
+      for (k in this._handlers)
+        delete this._handlers[k];
+      return this;
+    }
+
+    if (handler) {
+      for (i = 0, n = eArray.length; i !== n; i += 1) {
+        event = eArray[i];
+        if (this._handlers[event]) {
+          a = [];
+          for (j = 0, m = this._handlers[event].length; j !== m; j += 1)
+            if (this._handlers[event][j].handler !== handler)
+              a.push(this._handlers[event][j]);
+
+          this._handlers[event] = a;
+        }
+
+        if (this._handlers[event] && this._handlers[event].length === 0)
+          delete this._handlers[event];
+      }
+    } else
+      for (i = 0, n = eArray.length; i !== n; i += 1)
+        delete this._handlers[eArray[i]];
+
+    return this;
+  };
+
+  /**
+   * Executes each handler bound to the event
+   *
+   * @param  {string}     events The name of the event (or the events separated
+   *                             by spaces).
+   * @param  {?object}    data   The content of the event (optional).
+   * @return {dispatcher}        Returns the instance itself.
+   */
+  dispatcher.prototype.dispatchEvent = function(events, data) {
+    var i,
+        n,
+        j,
+        m,
+        a,
+        event,
+        eventName,
+        self = this,
+        eArray = typeof events === 'string' ? events.split(' ') : events;
+
+    data = data === undefined ? {} : data;
+
+    for (i = 0, n = eArray.length; i !== n; i += 1) {
+      eventName = eArray[i];
+
+      if (this._handlers[eventName]) {
+        event = self.getEvent(eventName, data);
+        a = [];
+
+        for (j = 0, m = this._handlers[eventName].length; j !== m; j += 1) {
+          this._handlers[eventName][j].handler(event);
+          if (!this._handlers[eventName][j].one)
+            a.push(this._handlers[eventName][j]);
+        }
+
+        this._handlers[eventName] = a;
+      }
+    }
+
+    return this;
+  };
+
+  /**
+   * Return an event object.
+   *
+   * @param  {string}  events The name of the event.
+   * @param  {?object} data   The content of the event (optional).
+   * @return {object}         Returns the instance itself.
+   */
+  dispatcher.prototype.getEvent = function(event, data) {
+    return {
+      type: event,
+      data: data || {},
+      target: this
+    };
+  };
+
+  /**
+   * A useful function to deal with inheritance. It will make the target
+   * inherit the prototype of the class dispatcher as well as its constructor.
+   *
+   * @param {object} target The target.
+   */
+  dispatcher.extend = function(target, args) {
+    var k;
+
+    for (k in dispatcher.prototype)
+      if (dispatcher.prototype.hasOwnProperty(k))
+        target[k] = dispatcher.prototype[k];
+
+    dispatcher.apply(target, args);
+  };
+
+
+
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof this.sigma !== 'undefined') {
+    this.sigma.classes = this.sigma.classes || {};
+    this.sigma.classes.dispatcher = dispatcher;
+  } else if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = dispatcher;
+    exports.dispatcher = dispatcher;
+  } else
+    this.dispatcher = dispatcher;
+}).call(this);
+
+;(function() {
+  'use strict';
+
+  /**
+   * This utils aims to facilitate the manipulation of each instance setting.
+   * Using a function instead of an object brings two main advantages: First,
+   * it will be easier in the future to catch settings updates through a
+   * function than an object. Second, giving it a full object will "merge" it
+   * to the settings object properly, keeping us to have to always add a loop.
+   *
+   * @return {configurable} The "settings" function.
+   */
+  var configurable = function() {
+    var i,
+        l,
+        data = {},
+        datas = Array.prototype.slice.call(arguments, 0);
+
+    /**
+     * The method to use to set or get any property of this instance.
+     *
+     * @param  {string|object}    a1 If it is a string and if a2 is undefined,
+     *                               then it will return the corresponding
+     *                               property. If it is a string and if a2 is
+     *                               set, then it will set a2 as the property
+     *                               corresponding to a1, and return this. If
+     *                               it is an object, then each pair string +
+     *                               object(or any other type) will be set as a
+     *                               property.
+     * @param  {*?}               a2 The new property corresponding to a1 if a1
+     *                               is a string.
+     * @return {*|configurable}      Returns itself or the corresponding
+     *                               property.
+     *
+     * Polymorphism:
+     * *************
+     * Here are some basic use examples:
+     *
+     *  > settings = new configurable();
+     *  > settings('mySetting', 42);
+     *  > settings('mySetting'); // Logs: 42
+     *  > settings('mySetting', 123);
+     *  > settings('mySetting'); // Logs: 123
+     *  > settings({mySetting: 456});
+     *  > settings('mySetting'); // Logs: 456
+     *
+     * Also, it is possible to use the function as a fallback:
+     *  > settings({mySetting: 'abc'}, 'mySetting');  // Logs: 'abc'
+     *  > settings({hisSetting: 'abc'}, 'mySetting'); // Logs: 456
+     */
+    var settings = function(a1, a2) {
+      var o,
+          i,
+          l,
+          k;
+
+      if (arguments.length === 1 && typeof a1 === 'string') {
+        if (data[a1] !== undefined)
+          return data[a1];
+        for (i = 0, l = datas.length; i < l; i++)
+          if (datas[i][a1] !== undefined)
+            return datas[i][a1];
+        return undefined;
+      } else if (typeof a1 === 'object' && typeof a2 === 'string') {
+        return (a1 || {})[a2] !== undefined ? a1[a2] : settings(a2);
+      } else {
+        o = (typeof a1 === 'object' && a2 === undefined) ? a1 : {};
+
+        if (typeof a1 === 'string')
+          o[a1] = a2;
+
+        for (i = 0, k = Object.keys(o), l = k.length; i < l; i++)
+          data[k[i]] = o[k[i]];
+
+        return this;
+      }
+    };
+
+    /**
+     * This method returns a new configurable function, with new objects
+     *
+     * @param  {object*}  Any number of objects to search in.
+     * @return {function} Returns the function. Check its documentation to know
+     *                    more about how it works.
+     */
+    settings.embedObjects = function() {
+      var args = datas.concat(
+        data
+      ).concat(
+        Array.prototype.splice.call(arguments, 0)
+      );
+
+      return configurable.apply({}, args);
+    };
+
+    // Initialize
+    for (i = 0, l = arguments.length; i < l; i++)
+      settings(arguments[i]);
+
+    return settings;
+  };
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof this.sigma !== 'undefined') {
+    this.sigma.classes = this.sigma.classes || {};
+    this.sigma.classes.configurable = configurable;
+  } else if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = configurable;
+    exports.configurable = configurable;
+  } else
+    this.configurable = configurable;
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  var _methods = Object.create(null),
+      _indexes = Object.create(null),
+      _initBindings = Object.create(null),
+      _methodBindings = Object.create(null),
+      _methodBeforeBindings = Object.create(null),
+      _defaultSettings = {
+        immutable: true,
+        clone: true
+      },
+      _defaultSettingsFunction = function(key) {
+        return _defaultSettings[key];
+      };
+
+  /**
+   * The graph constructor. It initializes the data and the indexes, and binds
+   * the custom indexes and methods to its own scope.
+   *
+   * Recognized parameters:
+   * **********************
+   * Here is the exhaustive list of every accepted parameters in the settings
+   * object:
+   *
+   *   {boolean} clone     Indicates if the data have to be cloned in methods
+   *                       to add nodes or edges.
+   *   {boolean} immutable Indicates if nodes "id" values and edges "id",
+   *                       "source" and "target" values must be set as
+   *                       immutable.
+   *
+   * @param  {?configurable} settings Eventually a settings function.
+   * @return {graph}                  The new graph instance.
+   */
+  var graph = function(settings) {
+    var k,
+        fn,
+        data;
+
+    /**
+     * DATA:
+     * *****
+     * Every data that is callable from graph methods are stored in this "data"
+     * object. This object will be served as context for all these methods,
+     * and it is possible to add other type of data in it.
+     */
+    data = {
+      /**
+       * SETTINGS FUNCTION:
+       * ******************
+       */
+      settings: settings || _defaultSettingsFunction,
+
+      /**
+       * MAIN DATA:
+       * **********
+       */
+      nodesArray: [],
+      edgesArray: [],
+
+      /**
+       * GLOBAL INDEXES:
+       * ***************
+       * These indexes just index data by ids.
+       */
+      nodesIndex: Object.create(null),
+      edgesIndex: Object.create(null),
+
+      /**
+       * LOCAL INDEXES:
+       * **************
+       * These indexes refer from node to nodes. Each key is an id, and each
+       * value is the array of the ids of related nodes.
+       */
+      inNeighborsIndex: Object.create(null),
+      outNeighborsIndex: Object.create(null),
+      allNeighborsIndex: Object.create(null),
+
+      inNeighborsCount: Object.create(null),
+      outNeighborsCount: Object.create(null),
+      allNeighborsCount: Object.create(null)
+    };
+
+    // Execute bindings:
+    for (k in _initBindings)
+      _initBindings[k].call(data);
+
+    // Add methods to both the scope and the data objects:
+    for (k in _methods) {
+      fn = __bindGraphMethod(k, data, _methods[k]);
+      this[k] = fn;
+      data[k] = fn;
+    }
+  };
+
+
+
+
+  /**
+   * A custom tool to bind methods such that function that are bound to it will
+   * be executed anytime the method is called.
+   *
+   * @param  {string}   methodName The name of the method to bind.
+   * @param  {object}   scope      The scope where the method must be executed.
+   * @param  {function} fn         The method itself.
+   * @return {function}            The new method.
+   */
+  function __bindGraphMethod(methodName, scope, fn) {
+    var result = function() {
+      var k,
+          res;
+
+      // Execute "before" bound functions:
+      for (k in _methodBeforeBindings[methodName])
+        _methodBeforeBindings[methodName][k].apply(scope, arguments);
+
+      // Apply the method:
+      res = fn.apply(scope, arguments);
+
+      // Execute bound functions:
+      for (k in _methodBindings[methodName])
+        _methodBindings[methodName][k].apply(scope, arguments);
+
+      // Return res:
+      return res;
+    };
+
+    return result;
+  }
+
+  /**
+   * This custom tool function removes every pair key/value from an hash. The
+   * goal is to avoid creating a new object while some other references are
+   * still hanging in some scopes...
+   *
+   * @param  {object} obj The object to empty.
+   * @return {object}     The empty object.
+   */
+  function __emptyObject(obj) {
+    var k;
+
+    for (k in obj)
+      if (!('hasOwnProperty' in obj) || obj.hasOwnProperty(k))
+        delete obj[k];
+
+    return obj;
+  }
+
+
+
+
+  /**
+   * This global method adds a method that will be bound to the futurly created
+   * graph instances.
+   *
+   * Since these methods will be bound to their scope when the instances are
+   * created, it does not use the prototype. Because of that, methods have to
+   * be added before instances are created to make them available.
+   *
+   * Here is an example:
+   *
+   *  > graph.addMethod('getNodesCount', function() {
+   *  >   return this.nodesArray.length;
+   *  > });
+   *  >
+   *  > var myGraph = new graph();
+   *  > console.log(myGraph.getNodesCount()); // outputs 0
+   *
+   * @param  {string}   methodName The name of the method.
+   * @param  {function} fn         The method itself.
+   * @return {object}              The global graph constructor.
+   */
+  graph.addMethod = function(methodName, fn) {
+    if (
+      typeof methodName !== 'string' ||
+      typeof fn !== 'function' ||
+      arguments.length !== 2
+    )
+      throw 'addMethod: Wrong arguments.';
+
+    if (_methods[methodName] || graph[methodName])
+      throw 'The method "' + methodName + '" already exists.';
+
+    _methods[methodName] = fn;
+    _methodBindings[methodName] = Object.create(null);
+    _methodBeforeBindings[methodName] = Object.create(null);
+
+    return this;
+  };
+
+  /**
+   * This global method returns true if the method has already been added, and
+   * false else.
+   *
+   * Here are some examples:
+   *
+   *  > graph.hasMethod('addNode'); // returns true
+   *  > graph.hasMethod('hasMethod'); // returns true
+   *  > graph.hasMethod('unexistingMethod'); // returns false
+   *
+   * @param  {string}  methodName The name of the method.
+   * @return {boolean}            The result.
+   */
+  graph.hasMethod = function(methodName) {
+    return !!(_methods[methodName] || graph[methodName]);
+  };
+
+  /**
+   * This global methods attaches a function to a method. Anytime the specified
+   * method is called, the attached function is called right after, with the
+   * same arguments and in the same scope. The attached function is called
+   * right before if the last argument is true, unless the method is the graph
+   * constructor.
+   *
+   * To attach a function to the graph constructor, use 'constructor' as the
+   * method name (first argument).
+   *
+   * The main idea is to have a clean way to keep custom indexes up to date,
+   * for instance:
+   *
+   *  > var timesAddNodeCalled = 0;
+   *  > graph.attach('addNode', 'timesAddNodeCalledInc', function() {
+   *  >   timesAddNodeCalled++;
+   *  > });
+   *  >
+   *  > var myGraph = new graph();
+   *  > console.log(timesAddNodeCalled); // outputs 0
+   *  >
+   *  > myGraph.addNode({ id: '1' }).addNode({ id: '2' });
+   *  > console.log(timesAddNodeCalled); // outputs 2
+   *
+   * The idea for calling a function before is to provide pre-processors, for
+   * instance:
+   *
+   *  > var colorPalette = { Person: '#C3CBE1', Place: '#9BDEBD' };
+   *  > graph.attach('addNode', 'applyNodeColorPalette', function(n) {
+   *  >   n.color = colorPalette[n.category];
+   *  > }, true);
+   *  >
+   *  > var myGraph = new graph();
+   *  > myGraph.addNode({ id: 'n0', category: 'Person' });
+   *  > console.log(myGraph.nodes('n0').color); // outputs '#C3CBE1'
+   *
+   * @param  {string}   methodName The name of the related method or
+   *                               "constructor".
+   * @param  {string}   key        The key to identify the function to attach.
+   * @param  {function} fn         The function to bind.
+   * @param  {boolean}  before     If true the function is called right before.
+   * @return {object}              The global graph constructor.
+   */
+  graph.attach = function(methodName, key, fn, before) {
+    if (
+      typeof methodName !== 'string' ||
+      typeof key !== 'string' ||
+      typeof fn !== 'function' ||
+      arguments.length < 3 ||
+      arguments.length > 4
+    )
+      throw 'attach: Wrong arguments.';
+
+    var bindings;
+
+    if (methodName === 'constructor')
+      bindings = _initBindings;
+    else {
+      if (before) {
+        if (!_methodBeforeBindings[methodName])
+        throw 'The method "' + methodName + '" does not exist.';
+
+        bindings = _methodBeforeBindings[methodName];
+      }
+      else {
+        if (!_methodBindings[methodName])
+          throw 'The method "' + methodName + '" does not exist.';
+
+        bindings = _methodBindings[methodName];
+      }
+    }
+
+    if (bindings[key])
+      throw 'A function "' + key + '" is already attached ' +
+            'to the method "' + methodName + '".';
+
+    bindings[key] = fn;
+
+    return this;
+  };
+
+  /**
+   * Alias of attach(methodName, key, fn, true).
+   */
+  graph.attachBefore = function(methodName, key, fn) {
+    return this.attach(methodName, key, fn, true);
+  };
+
+  /**
+   * This methods is just an helper to deal with custom indexes. It takes as
+   * arguments the name of the index and an object containing all the different
+   * functions to bind to the methods.
+   *
+   * Here is a basic example, that creates an index to keep the number of nodes
+   * in the current graph. It also adds a method to provide a getter on that
+   * new index:
+   *
+   *  > sigma.classes.graph.addIndex('nodesCount', {
+   *  >   constructor: function() {
+   *  >     this.nodesCount = 0;
+   *  >   },
+   *  >   addNode: function() {
+   *  >     this.nodesCount++;
+   *  >   },
+   *  >   dropNode: function() {
+   *  >     this.nodesCount--;
+   *  >   }
+   *  > });
+   *  >
+   *  > sigma.classes.graph.addMethod('getNodesCount', function() {
+   *  >   return this.nodesCount;
+   *  > });
+   *  >
+   *  > var myGraph = new sigma.classes.graph();
+   *  > console.log(myGraph.getNodesCount()); // outputs 0
+   *  >
+   *  > myGraph.addNode({ id: '1' }).addNode({ id: '2' });
+   *  > console.log(myGraph.getNodesCount()); // outputs 2
+   *
+   * @param  {string} name     The name of the index.
+   * @param  {object} bindings The object containing the functions to bind.
+   * @return {object}          The global graph constructor.
+   */
+  graph.addIndex = function(name, bindings) {
+    if (
+      typeof name !== 'string' ||
+      Object(bindings) !== bindings ||
+      arguments.length !== 2
+    )
+      throw 'addIndex: Wrong arguments.';
+
+    if (_indexes[name])
+      throw 'The index "' + name + '" already exists.';
+
+    var k;
+
+    // Store the bindings:
+    _indexes[name] = bindings;
+
+    // Attach the bindings:
+    for (k in bindings)
+      if (typeof bindings[k] !== 'function')
+        throw 'The bindings must be functions.';
+      else
+        graph.attach(k, name, bindings[k]);
+
+    return this;
+  };
+
+
+
+
+  /**
+   * This method adds a node to the graph. The node must be an object, with a
+   * string under the key "id". Except for this, it is possible to add any
+   * other attribute, that will be preserved all along the manipulations.
+   *
+   * If the graph option "clone" has a truthy value, the node will be cloned
+   * when added to the graph. Also, if the graph option "immutable" has a
+   * truthy value, its id will be defined as immutable.
+   *
+   * @param  {object} node The node to add.
+   * @return {object}      The graph instance.
+   */
+  graph.addMethod('addNode', function(node) {
+    // Check that the node is an object and has an id:
+    if (Object(node) !== node || arguments.length !== 1)
+      throw 'addNode: Wrong arguments.';
+
+    if (typeof node.id !== 'string' && typeof node.id !== 'number')
+      throw 'The node must have a string or number id.';
+
+    if (this.nodesIndex[node.id])
+      throw 'The node "' + node.id + '" already exists.';
+
+    var k,
+        id = node.id,
+        validNode = Object.create(null);
+
+    // Check the "clone" option:
+    if (this.settings('clone')) {
+      for (k in node)
+        if (k !== 'id')
+          validNode[k] = node[k];
+    } else
+      validNode = node;
+
+    // Check the "immutable" option:
+    if (this.settings('immutable'))
+      Object.defineProperty(validNode, 'id', {
+        value: id,
+        enumerable: true
+      });
+    else
+      validNode.id = id;
+
+    // Add empty containers for edges indexes:
+    this.inNeighborsIndex[id] = Object.create(null);
+    this.outNeighborsIndex[id] = Object.create(null);
+    this.allNeighborsIndex[id] = Object.create(null);
+
+    this.inNeighborsCount[id] = 0;
+    this.outNeighborsCount[id] = 0;
+    this.allNeighborsCount[id] = 0;
+
+    // Add the node to indexes:
+    this.nodesArray.push(validNode);
+    this.nodesIndex[validNode.id] = validNode;
+
+    // Return the current instance:
+    return this;
+  });
+
+  /**
+   * This method adds an edge to the graph. The edge must be an object, with a
+   * string under the key "id", and strings under the keys "source" and
+   * "target" that design existing nodes. Except for this, it is possible to
+   * add any other attribute, that will be preserved all along the
+   * manipulations.
+   *
+   * If the graph option "clone" has a truthy value, the edge will be cloned
+   * when added to the graph. Also, if the graph option "immutable" has a
+   * truthy value, its id, source and target will be defined as immutable.
+   *
+   * @param  {object} edge The edge to add.
+   * @return {object}      The graph instance.
+   */
+  graph.addMethod('addEdge', function(edge) {
+    // Check that the edge is an object and has an id:
+    if (Object(edge) !== edge || arguments.length !== 1)
+      throw 'addEdge: Wrong arguments.';
+
+    if (typeof edge.id !== 'string' && typeof edge.id !== 'number')
+      throw 'The edge must have a string or number id.';
+
+    if ((typeof edge.source !== 'string' && typeof edge.source !== 'number') ||
+        !this.nodesIndex[edge.source])
+      throw 'The edge source must have an existing node id.';
+
+    if ((typeof edge.target !== 'string' && typeof edge.target !== 'number') ||
+        !this.nodesIndex[edge.target])
+      throw 'The edge target must have an existing node id.';
+
+    if (this.edgesIndex[edge.id])
+      throw 'The edge "' + edge.id + '" already exists.';
+
+    var k,
+        validEdge = Object.create(null);
+
+    // Check the "clone" option:
+    if (this.settings('clone')) {
+      for (k in edge)
+        if (k !== 'id' && k !== 'source' && k !== 'target')
+          validEdge[k] = edge[k];
+    } else
+      validEdge = edge;
+
+    // Check the "immutable" option:
+    if (this.settings('immutable')) {
+      Object.defineProperty(validEdge, 'id', {
+        value: edge.id,
+        enumerable: true
+      });
+
+      Object.defineProperty(validEdge, 'source', {
+        value: edge.source,
+        enumerable: true
+      });
+
+      Object.defineProperty(validEdge, 'target', {
+        value: edge.target,
+        enumerable: true
+      });
+    } else {
+      validEdge.id = edge.id;
+      validEdge.source = edge.source;
+      validEdge.target = edge.target;
+    }
+
+    // Add the edge to indexes:
+    this.edgesArray.push(validEdge);
+    this.edgesIndex[validEdge.id] = validEdge;
+
+    if (!this.inNeighborsIndex[validEdge.target][validEdge.source])
+      this.inNeighborsIndex[validEdge.target][validEdge.source] =
+        Object.create(null);
+    this.inNeighborsIndex[validEdge.target][validEdge.source][validEdge.id] =
+      validEdge;
+
+    if (!this.outNeighborsIndex[validEdge.source][validEdge.target])
+      this.outNeighborsIndex[validEdge.source][validEdge.target] =
+        Object.create(null);
+    this.outNeighborsIndex[validEdge.source][validEdge.target][validEdge.id] =
+      validEdge;
+
+    if (!this.allNeighborsIndex[validEdge.source][validEdge.target])
+      this.allNeighborsIndex[validEdge.source][validEdge.target] =
+        Object.create(null);
+    this.allNeighborsIndex[validEdge.source][validEdge.target][validEdge.id] =
+      validEdge;
+
+    if (validEdge.target !== validEdge.source) {
+      if (!this.allNeighborsIndex[validEdge.target][validEdge.source])
+        this.allNeighborsIndex[validEdge.target][validEdge.source] =
+          Object.create(null);
+      this.allNeighborsIndex[validEdge.target][validEdge.source][validEdge.id] =
+        validEdge;
+    }
+
+    // Keep counts up to date:
+    this.inNeighborsCount[validEdge.target]++;
+    this.outNeighborsCount[validEdge.source]++;
+    this.allNeighborsCount[validEdge.target]++;
+    this.allNeighborsCount[validEdge.source]++;
+
+    return this;
+  });
+
+  /**
+   * This method drops a node from the graph. It also removes each edge that is
+   * bound to it, through the dropEdge method. An error is thrown if the node
+   * does not exist.
+   *
+   * @param  {string} id The node id.
+   * @return {object}    The graph instance.
+   */
+  graph.addMethod('dropNode', function(id) {
+    // Check that the arguments are valid:
+    if ((typeof id !== 'string' && typeof id !== 'number') ||
+        arguments.length !== 1)
+      throw 'dropNode: Wrong arguments.';
+
+    if (!this.nodesIndex[id])
+      throw 'The node "' + id + '" does not exist.';
+
+    var i, k, l;
+
+    // Remove the node from indexes:
+    delete this.nodesIndex[id];
+    for (i = 0, l = this.nodesArray.length; i < l; i++)
+      if (this.nodesArray[i].id === id) {
+        this.nodesArray.splice(i, 1);
+        break;
+      }
+
+    // Remove related edges:
+    for (i = this.edgesArray.length - 1; i >= 0; i--)
+      if (this.edgesArray[i].source === id || this.edgesArray[i].target === id)
+        this.dropEdge(this.edgesArray[i].id);
+
+    // Remove related edge indexes:
+    delete this.inNeighborsIndex[id];
+    delete this.outNeighborsIndex[id];
+    delete this.allNeighborsIndex[id];
+
+    delete this.inNeighborsCount[id];
+    delete this.outNeighborsCount[id];
+    delete this.allNeighborsCount[id];
+
+    for (k in this.nodesIndex) {
+      delete this.inNeighborsIndex[k][id];
+      delete this.outNeighborsIndex[k][id];
+      delete this.allNeighborsIndex[k][id];
+    }
+
+    return this;
+  });
+
+  /**
+   * This method drops an edge from the graph. An error is thrown if the edge
+   * does not exist.
+   *
+   * @param  {string} id The edge id.
+   * @return {object}    The graph instance.
+   */
+  graph.addMethod('dropEdge', function(id) {
+    // Check that the arguments are valid:
+    if ((typeof id !== 'string' && typeof id !== 'number') ||
+        arguments.length !== 1)
+      throw 'dropEdge: Wrong arguments.';
+
+    if (!this.edgesIndex[id])
+      throw 'The edge "' + id + '" does not exist.';
+
+    var i, l, edge;
+
+    // Remove the edge from indexes:
+    edge = this.edgesIndex[id];
+    delete this.edgesIndex[id];
+    for (i = 0, l = this.edgesArray.length; i < l; i++)
+      if (this.edgesArray[i].id === id) {
+        this.edgesArray.splice(i, 1);
+        break;
+      }
+
+    delete this.inNeighborsIndex[edge.target][edge.source][edge.id];
+    if (!Object.keys(this.inNeighborsIndex[edge.target][edge.source]).length)
+      delete this.inNeighborsIndex[edge.target][edge.source];
+
+    delete this.outNeighborsIndex[edge.source][edge.target][edge.id];
+    if (!Object.keys(this.outNeighborsIndex[edge.source][edge.target]).length)
+      delete this.outNeighborsIndex[edge.source][edge.target];
+
+    delete this.allNeighborsIndex[edge.source][edge.target][edge.id];
+    if (!Object.keys(this.allNeighborsIndex[edge.source][edge.target]).length)
+      delete this.allNeighborsIndex[edge.source][edge.target];
+
+    if (edge.target !== edge.source) {
+      delete this.allNeighborsIndex[edge.target][edge.source][edge.id];
+      if (!Object.keys(this.allNeighborsIndex[edge.target][edge.source]).length)
+        delete this.allNeighborsIndex[edge.target][edge.source];
+    }
+
+    this.inNeighborsCount[edge.target]--;
+    this.outNeighborsCount[edge.source]--;
+    this.allNeighborsCount[edge.source]--;
+    this.allNeighborsCount[edge.target]--;
+
+    return this;
+  });
+
+  /**
+   * This method destroys the current instance. It basically empties each index
+   * and methods attached to the graph.
+   */
+  graph.addMethod('kill', function() {
+    // Delete arrays:
+    this.nodesArray.length = 0;
+    this.edgesArray.length = 0;
+    delete this.nodesArray;
+    delete this.edgesArray;
+
+    // Delete indexes:
+    delete this.nodesIndex;
+    delete this.edgesIndex;
+    delete this.inNeighborsIndex;
+    delete this.outNeighborsIndex;
+    delete this.allNeighborsIndex;
+    delete this.inNeighborsCount;
+    delete this.outNeighborsCount;
+    delete this.allNeighborsCount;
+  });
+
+  /**
+   * This method empties the nodes and edges arrays, as well as the different
+   * indexes.
+   *
+   * @return {object} The graph instance.
+   */
+  graph.addMethod('clear', function() {
+    this.nodesArray.length = 0;
+    this.edgesArray.length = 0;
+
+    // Due to GC issues, I prefer not to create new object. These objects are
+    // only available from the methods and attached functions, but still, it is
+    // better to prevent ghost references to unrelevant data...
+    __emptyObject(this.nodesIndex);
+    __emptyObject(this.edgesIndex);
+    __emptyObject(this.nodesIndex);
+    __emptyObject(this.inNeighborsIndex);
+    __emptyObject(this.outNeighborsIndex);
+    __emptyObject(this.allNeighborsIndex);
+    __emptyObject(this.inNeighborsCount);
+    __emptyObject(this.outNeighborsCount);
+    __emptyObject(this.allNeighborsCount);
+
+    return this;
+  });
+
+  /**
+   * This method reads an object and adds the nodes and edges, through the
+   * proper methods "addNode" and "addEdge".
+   *
+   * Here is an example:
+   *
+   *  > var myGraph = new graph();
+   *  > myGraph.read({
+   *  >   nodes: [
+   *  >     { id: 'n0' },
+   *  >     { id: 'n1' }
+   *  >   ],
+   *  >   edges: [
+   *  >     {
+   *  >       id: 'e0',
+   *  >       source: 'n0',
+   *  >       target: 'n1'
+   *  >     }
+   *  >   ]
+   *  > });
+   *  >
+   *  > console.log(
+   *  >   myGraph.nodes().length,
+   *  >   myGraph.edges().length
+   *  > ); // outputs 2 1
+   *
+   * @param  {object} g The graph object.
+   * @return {object}   The graph instance.
+   */
+  graph.addMethod('read', function(g) {
+    var i,
+        a,
+        l;
+
+    a = g.nodes || [];
+    for (i = 0, l = a.length; i < l; i++)
+      this.addNode(a[i]);
+
+    a = g.edges || [];
+    for (i = 0, l = a.length; i < l; i++)
+      this.addEdge(a[i]);
+
+    return this;
+  });
+
+  /**
+   * This methods returns one or several nodes, depending on how it is called.
+   *
+   * To get the array of nodes, call "nodes" without argument. To get a
+   * specific node, call it with the id of the node. The get multiple node,
+   * call it with an array of ids, and it will return the array of nodes, in
+   * the same order.
+   *
+   * @param  {?(string|array)} v Eventually one id, an array of ids.
+   * @return {object|array}      The related node or array of nodes.
+   */
+  graph.addMethod('nodes', function(v) {
+    // Clone the array of nodes and return it:
+    if (!arguments.length)
+      return this.nodesArray.slice(0);
+
+    // Return the related node:
+    if (arguments.length === 1 &&
+        (typeof v === 'string' || typeof v === 'number'))
+      return this.nodesIndex[v];
+
+    // Return an array of the related node:
+    if (
+      arguments.length === 1 &&
+      Object.prototype.toString.call(v) === '[object Array]'
+    ) {
+      var i,
+          l,
+          a = [];
+
+      for (i = 0, l = v.length; i < l; i++)
+        if (typeof v[i] === 'string' || typeof v[i] === 'number')
+          a.push(this.nodesIndex[v[i]]);
+        else
+          throw 'nodes: Wrong arguments.';
+
+      return a;
+    }
+
+    throw 'nodes: Wrong arguments.';
+  });
+
+  /**
+   * This methods returns the degree of one or several nodes, depending on how
+   * it is called. It is also possible to get incoming or outcoming degrees
+   * instead by specifying 'in' or 'out' as a second argument.
+   *
+   * @param  {string|array} v     One id, an array of ids.
+   * @param  {?string}      which Which degree is required. Values are 'in',
+   *                              'out', and by default the normal degree.
+   * @return {number|array}       The related degree or array of degrees.
+   */
+  graph.addMethod('degree', function(v, which) {
+    // Check which degree is required:
+    which = {
+      'in': this.inNeighborsCount,
+      'out': this.outNeighborsCount
+    }[which || ''] || this.allNeighborsCount;
+
+    // Return the related node:
+    if (typeof v === 'string' || typeof v === 'number')
+      return which[v];
+
+    // Return an array of the related node:
+    if (Object.prototype.toString.call(v) === '[object Array]') {
+      var i,
+          l,
+          a = [];
+
+      for (i = 0, l = v.length; i < l; i++)
+        if (typeof v[i] === 'string' || typeof v[i] === 'number')
+          a.push(which[v[i]]);
+        else
+          throw 'degree: Wrong arguments.';
+
+      return a;
+    }
+
+    throw 'degree: Wrong arguments.';
+  });
+
+  /**
+   * This methods returns one or several edges, depending on how it is called.
+   *
+   * To get the array of edges, call "edges" without argument. To get a
+   * specific edge, call it with the id of the edge. The get multiple edge,
+   * call it with an array of ids, and it will return the array of edges, in
+   * the same order.
+   *
+   * @param  {?(string|array)} v Eventually one id, an array of ids.
+   * @return {object|array}      The related edge or array of edges.
+   */
+  graph.addMethod('edges', function(v) {
+    // Clone the array of edges and return it:
+    if (!arguments.length)
+      return this.edgesArray.slice(0);
+
+    // Return the related edge:
+    if (arguments.length === 1 &&
+        (typeof v === 'string' || typeof v === 'number'))
+      return this.edgesIndex[v];
+
+    // Return an array of the related edge:
+    if (
+      arguments.length === 1 &&
+      Object.prototype.toString.call(v) === '[object Array]'
+    ) {
+      var i,
+          l,
+          a = [];
+
+      for (i = 0, l = v.length; i < l; i++)
+        if (typeof v[i] === 'string' || typeof v[i] === 'number')
+          a.push(this.edgesIndex[v[i]]);
+        else
+          throw 'edges: Wrong arguments.';
+
+      return a;
+    }
+
+    throw 'edges: Wrong arguments.';
+  });
+
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof sigma !== 'undefined') {
+    sigma.classes = sigma.classes || Object.create(null);
+    sigma.classes.graph = graph;
+  } else if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = graph;
+    exports.graph = graph;
+  } else
+    this.graph = graph;
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  sigma.utils.pkg('sigma.classes');
+
+  /**
+   * The camera constructor. It just initializes its attributes and methods.
+   *
+   * @param  {string}       id       The id.
+   * @param  {sigma.classes.graph}  graph    The graph.
+   * @param  {configurable} settings The settings function.
+   * @param  {?object}      options  Eventually some overriding options.
+   * @return {camera}                Returns the fresh new camera instance.
+   */
+  sigma.classes.camera = function(id, graph, settings, options) {
+    sigma.classes.dispatcher.extend(this);
+
+    Object.defineProperty(this, 'graph', {
+      value: graph
+    });
+    Object.defineProperty(this, 'id', {
+      value: id
+    });
+    Object.defineProperty(this, 'readPrefix', {
+      value: 'read_cam' + id + ':'
+    });
+    Object.defineProperty(this, 'prefix', {
+      value: 'cam' + id + ':'
+    });
+
+    this.x = 0;
+    this.y = 0;
+    this.ratio = 1;
+    this.angle = 0;
+    this.isAnimated = false;
+    this.settings = (typeof options === 'object' && options) ?
+      settings.embedObject(options) :
+      settings;
+  };
+
+  /**
+   * Updates the camera position.
+   *
+   * @param  {object} coordinates The new coordinates object.
+   * @return {camera}             Returns the camera.
+   */
+  sigma.classes.camera.prototype.goTo = function(coordinates) {
+    if (!this.settings('enableCamera'))
+      return this;
+
+    var i,
+        l,
+        c = coordinates || {},
+        keys = ['x', 'y', 'ratio', 'angle'];
+
+    for (i = 0, l = keys.length; i < l; i++)
+      if (c[keys[i]] !== undefined) {
+        if (typeof c[keys[i]] === 'number' && !isNaN(c[keys[i]]))
+          this[keys[i]] = c[keys[i]];
+        else
+          throw 'Value for "' + keys[i] + '" is not a number.';
+      }
+
+    this.dispatchEvent('coordinatesUpdated');
+    return this;
+  };
+
+  /**
+   * This method takes a graph and computes for each node and edges its
+   * coordinates relatively to the center of the camera. Basically, it will
+   * compute the coordinates that will be used by the graphic renderers.
+   *
+   * Since it should be possible to use different cameras and different
+   * renderers, it is possible to specify a prefix to put before the new
+   * coordinates (to get something like "node.camera1_x")
+   *
+   * @param  {?string} read    The prefix of the coordinates to read.
+   * @param  {?string} write   The prefix of the coordinates to write.
+   * @param  {?object} options Eventually an object of options. Those can be:
+   *                           - A restricted nodes array.
+   *                           - A restricted edges array.
+   *                           - A width.
+   *                           - A height.
+   * @return {camera}        Returns the camera.
+   */
+  sigma.classes.camera.prototype.applyView = function(read, write, options) {
+    options = options || {};
+    write = write !== undefined ? write : this.prefix;
+    read = read !== undefined ? read : this.readPrefix;
+
+    var nodes = options.nodes || this.graph.nodes(),
+        edges = options.edges || this.graph.edges();
+
+    var i,
+        l,
+        node,
+        cos = Math.cos(this.angle),
+        sin = Math.sin(this.angle),
+        nodeRatio = Math.pow(this.ratio, this.settings('nodesPowRatio')),
+        edgeRatio = Math.pow(this.ratio, this.settings('edgesPowRatio')),
+        xOffset = (options.width || 0) / 2,
+        yOffset = (options.height || 0) / 2;
+
+    for (i = 0, l = nodes.length; i < l; i++) {
+      node = nodes[i];
+      node[write + 'x'] =
+        (
+          ((node[read + 'x'] || 0) - this.x) * cos +
+          ((node[read + 'y'] || 0) - this.y) * sin
+        ) / this.ratio + xOffset;
+      node[write + 'y'] =
+        (
+          ((node[read + 'y'] || 0) - this.y) * cos -
+          ((node[read + 'x'] || 0) - this.x) * sin
+        ) / this.ratio + yOffset;
+      node[write + 'size'] =
+        (node[read + 'size'] || 0) /
+        nodeRatio;
+    }
+
+    for (i = 0, l = edges.length; i < l; i++) {
+      edges[i][write + 'size'] =
+        (edges[i][read + 'size'] || 0) /
+        edgeRatio;
+    }
+
+    return this;
+  };
+
+  /**
+   * This function converts the coordinates of a point from the frame of the
+   * camera to the frame of the graph.
+   *
+   * @param  {number} x The X coordinate of the point in the frame of the
+   *                    camera.
+   * @param  {number} y The Y coordinate of the point in the frame of the
+   *                    camera.
+   * @return {object}   The point coordinates in the frame of the graph.
+   */
+  sigma.classes.camera.prototype.graphPosition = function(x, y, vector) {
+    var X = 0,
+        Y = 0,
+        cos = Math.cos(this.angle),
+        sin = Math.sin(this.angle);
+
+    // Revert the origin differential vector:
+    if (!vector) {
+      X = - (this.x * cos + this.y * sin) / this.ratio;
+      Y = - (this.y * cos - this.x * sin) / this.ratio;
+    }
+
+    return {
+      x: (x * cos + y * sin) / this.ratio + X,
+      y: (y * cos - x * sin) / this.ratio + Y
+    };
+  };
+
+  /**
+   * This function converts the coordinates of a point from the frame of the
+   * graph to the frame of the camera.
+   *
+   * @param  {number} x The X coordinate of the point in the frame of the
+   *                    graph.
+   * @param  {number} y The Y coordinate of the point in the frame of the
+   *                    graph.
+   * @return {object}   The point coordinates in the frame of the camera.
+   */
+  sigma.classes.camera.prototype.cameraPosition = function(x, y, vector) {
+    var X = 0,
+        Y = 0,
+        cos = Math.cos(this.angle),
+        sin = Math.sin(this.angle);
+
+    // Revert the origin differential vector:
+    if (!vector) {
+      X = - (this.x * cos + this.y * sin) / this.ratio;
+      Y = - (this.y * cos - this.x * sin) / this.ratio;
+    }
+
+    return {
+      x: ((x - X) * cos - (y - Y) * sin) * this.ratio,
+      y: ((y - Y) * cos + (x - X) * sin) * this.ratio
+    };
+  };
+
+  /**
+   * This method returns the transformation matrix of the camera. This is
+   * especially useful to apply the camera view directly in shaders, in case of
+   * WebGL rendering.
+   *
+   * @return {array} The transformation matrix.
+   */
+  sigma.classes.camera.prototype.getMatrix = function() {
+    var scale = sigma.utils.matrices.scale(1 / this.ratio),
+        rotation = sigma.utils.matrices.rotation(this.angle),
+        translation = sigma.utils.matrices.translation(-this.x, -this.y),
+        matrix = sigma.utils.matrices.multiply(
+          translation,
+          sigma.utils.matrices.multiply(
+            rotation,
+            scale
+          )
+        );
+
+    return matrix;
+  };
+
+  /**
+   * Taking a width and a height as parameters, this method returns the
+   * coordinates of the rectangle representing the camera on screen, in the
+   * graph's referentiel.
+   *
+   * To keep displaying labels of nodes going out of the screen, the method
+   * keeps a margin around the screen in the returned rectangle.
+   *
+   * @param  {number} width  The width of the screen.
+   * @param  {number} height The height of the screen.
+   * @return {object}        The rectangle as x1, y1, x2 and y2, representing
+   *                         two opposite points.
+   */
+  sigma.classes.camera.prototype.getRectangle = function(width, height) {
+    var widthVect = this.cameraPosition(width, 0, true),
+        heightVect = this.cameraPosition(0, height, true),
+        centerVect = this.cameraPosition(width / 2, height / 2, true),
+        marginX = this.cameraPosition(width / 4, 0, true).x,
+        marginY = this.cameraPosition(0, height / 4, true).y;
+
+    return {
+      x1: this.x - centerVect.x - marginX,
+      y1: this.y - centerVect.y - marginY,
+      x2: this.x - centerVect.x + marginX + widthVect.x,
+      y2: this.y - centerVect.y - marginY + widthVect.y,
+      height: Math.sqrt(
+        Math.pow(heightVect.x, 2) +
+        Math.pow(heightVect.y + 2 * marginY, 2)
+      )
+    };
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  /**
+   * Sigma Quadtree Module
+   * =====================
+   *
+   * Author: Guillaume Plique (Yomguithereal)
+   * Version: 0.2
+   */
+
+
+
+  /**
+   * Quad Geometric Operations
+   * -------------------------
+   *
+   * A useful batch of geometric operations used by the quadtree.
+   */
+
+  var _geom = {
+
+    /**
+     * Transforms a graph node with x, y and size into an
+     * axis-aligned square.
+     *
+     * @param  {object} A graph node with at least a point (x, y) and a size.
+     * @return {object} A square: two points (x1, y1), (x2, y2) and height.
+     */
+    pointToSquare: function(n) {
+      return {
+        x1: n.x - n.size,
+        y1: n.y - n.size,
+        x2: n.x + n.size,
+        y2: n.y - n.size,
+        height: n.size * 2
+      };
+    },
+
+    /**
+     * Checks whether a rectangle is axis-aligned.
+     *
+     * @param  {object}  A rectangle defined by two points
+     *                   (x1, y1) and (x2, y2).
+     * @return {boolean} True if the rectangle is axis-aligned.
+     */
+    isAxisAligned: function(r) {
+      return r.x1 === r.x2 || r.y1 === r.y2;
+    },
+
+    /**
+     * Compute top points of an axis-aligned rectangle. This is useful in
+     * cases when the rectangle has been rotated (left, right or bottom up) and
+     * later operations need to know the top points.
+     *
+     * @param  {object} An axis-aligned rectangle defined by two points
+     *                  (x1, y1), (x2, y2) and height.
+     * @return {object} A rectangle: two points (x1, y1), (x2, y2) and height.
+     */
+    axisAlignedTopPoints: function(r) {
+
+      // Basic
+      if (r.y1 === r.y2 && r.x1 < r.x2)
+        return r;
+
+      // Rotated to right
+      if (r.x1 === r.x2 && r.y2 > r.y1)
+        return {
+          x1: r.x1 - r.height, y1: r.y1,
+          x2: r.x1, y2: r.y1,
+          height: r.height
+        };
+
+      // Rotated to left
+      if (r.x1 === r.x2 && r.y2 < r.y1)
+        return {
+          x1: r.x1, y1: r.y2,
+          x2: r.x2 + r.height, y2: r.y2,
+          height: r.height
+        };
+
+      // Bottom's up
+      return {
+        x1: r.x2, y1: r.y1 - r.height,
+        x2: r.x1, y2: r.y1 - r.height,
+        height: r.height
+      };
+    },
+
+    /**
+     * Get coordinates of a rectangle's lower left corner from its top points.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @return {object} Coordinates of the corner (x, y).
+     */
+    lowerLeftCoor: function(r) {
+      var width = (
+        Math.sqrt(
+          Math.pow(r.x2 - r.x1, 2) +
+          Math.pow(r.y2 - r.y1, 2)
+        )
+      );
+
+      return {
+        x: r.x1 - (r.y2 - r.y1) * r.height / width,
+        y: r.y1 + (r.x2 - r.x1) * r.height / width
+      };
+    },
+
+    /**
+     * Get coordinates of a rectangle's lower right corner from its top points
+     * and its lower left corner.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @param  {object} A corner's coordinates (x, y).
+     * @return {object} Coordinates of the corner (x, y).
+     */
+    lowerRightCoor: function(r, llc) {
+      return {
+        x: llc.x - r.x1 + r.x2,
+        y: llc.y - r.y1 + r.y2
+      };
+    },
+
+    /**
+     * Get the coordinates of all the corners of a rectangle from its top point.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @return {array}  An array of the four corners' coordinates (x, y).
+     */
+    rectangleCorners: function(r) {
+      var llc = this.lowerLeftCoor(r),
+          lrc = this.lowerRightCoor(r, llc);
+
+      return [
+        {x: r.x1, y: r.y1},
+        {x: r.x2, y: r.y2},
+        {x: llc.x, y: llc.y},
+        {x: lrc.x, y: lrc.y}
+      ];
+    },
+
+    /**
+     * Split a square defined by its boundaries into four.
+     *
+     * @param  {object} Boundaries of the square (x, y, width, height).
+     * @return {array}  An array containing the four new squares, themselves
+     *                  defined by an array of their four corners (x, y).
+     */
+    splitSquare: function(b) {
+      return [
+        [
+          {x: b.x, y: b.y},
+          {x: b.x + b.width / 2, y: b.y},
+          {x: b.x, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2}
+        ],
+        [
+          {x: b.x + b.width / 2, y: b.y},
+          {x: b.x + b.width, y: b.y},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x + b.width, y: b.y + b.height / 2}
+        ],
+        [
+          {x: b.x, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x, y: b.y + b.height},
+          {x: b.x + b.width / 2, y: b.y + b.height}
+        ],
+        [
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x + b.width, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height},
+          {x: b.x + b.width, y: b.y + b.height}
+        ]
+      ];
+    },
+
+    /**
+     * Compute the four axis between corners of rectangle A and corners of
+     * rectangle B. This is needed later to check an eventual collision.
+     *
+     * @param  {array} An array of rectangle A's four corners (x, y).
+     * @param  {array} An array of rectangle B's four corners (x, y).
+     * @return {array} An array of four axis defined by their coordinates (x,y).
+     */
+    axis: function(c1, c2) {
+      return [
+        {x: c1[1].x - c1[0].x, y: c1[1].y - c1[0].y},
+        {x: c1[1].x - c1[3].x, y: c1[1].y - c1[3].y},
+        {x: c2[0].x - c2[2].x, y: c2[0].y - c2[2].y},
+        {x: c2[0].x - c2[1].x, y: c2[0].y - c2[1].y}
+      ];
+    },
+
+    /**
+     * Project a rectangle's corner on an axis.
+     *
+     * @param  {object} Coordinates of a corner (x, y).
+     * @param  {object} Coordinates of an axis (x, y).
+     * @return {object} The projection defined by coordinates (x, y).
+     */
+    projection: function(c, a) {
+      var l = (
+        (c.x * a.x + c.y * a.y) /
+        (Math.pow(a.x, 2) + Math.pow(a.y, 2))
+      );
+
+      return {
+        x: l * a.x,
+        y: l * a.y
+      };
+    },
+
+    /**
+     * Check whether two rectangles collide on one particular axis.
+     *
+     * @param  {object}   An axis' coordinates (x, y).
+     * @param  {array}    Rectangle A's corners.
+     * @param  {array}    Rectangle B's corners.
+     * @return {boolean}  True if the rectangles collide on the axis.
+     */
+    axisCollision: function(a, c1, c2) {
+      var sc1 = [],
+          sc2 = [];
+
+      for (var ci = 0; ci < 4; ci++) {
+        var p1 = this.projection(c1[ci], a),
+            p2 = this.projection(c2[ci], a);
+
+        sc1.push(p1.x * a.x + p1.y * a.y);
+        sc2.push(p2.x * a.x + p2.y * a.y);
+      }
+
+      var maxc1 = Math.max.apply(Math, sc1),
+          maxc2 = Math.max.apply(Math, sc2),
+          minc1 = Math.min.apply(Math, sc1),
+          minc2 = Math.min.apply(Math, sc2);
+
+      return (minc2 <= maxc1 && maxc2 >= minc1);
+    },
+
+    /**
+     * Check whether two rectangles collide on each one of their four axis. If
+     * all axis collide, then the two rectangles do collide on the plane.
+     *
+     * @param  {array}    Rectangle A's corners.
+     * @param  {array}    Rectangle B's corners.
+     * @return {boolean}  True if the rectangles collide.
+     */
+    collision: function(c1, c2) {
+      var axis = this.axis(c1, c2),
+          col = true;
+
+      for (var i = 0; i < 4; i++)
+        col = col && this.axisCollision(axis[i], c1, c2);
+
+      return col;
+    }
+  };
+
+
+  /**
+   * Quad Functions
+   * ------------
+   *
+   * The Quadtree functions themselves.
+   * For each of those functions, we consider that in a splitted quad, the
+   * index of each node is the following:
+   * 0: top left
+   * 1: top right
+   * 2: bottom left
+   * 3: bottom right
+   *
+   * Moreover, the hereafter quad's philosophy is to consider that if an element
+   * collides with more than one nodes, this element belongs to each of the
+   * nodes it collides with where other would let it lie on a higher node.
+   */
+
+  /**
+   * Get the index of the node containing the point in the quad
+   *
+   * @param  {object}  point      A point defined by coordinates (x, y).
+   * @param  {object}  quadBounds Boundaries of the quad (x, y, width, heigth).
+   * @return {integer}            The index of the node containing the point.
+   */
+  function _quadIndex(point, quadBounds) {
+    var xmp = quadBounds.x + quadBounds.width / 2,
+        ymp = quadBounds.y + quadBounds.height / 2,
+        top = (point.y < ymp),
+        left = (point.x < xmp);
+
+    if (top) {
+      if (left)
+        return 0;
+      else
+        return 1;
+    }
+    else {
+      if (left)
+        return 2;
+      else
+        return 3;
+    }
+  }
+
+  /**
+   * Get a list of indexes of nodes containing an axis-aligned rectangle
+   *
+   * @param  {object}  rectangle   A rectangle defined by two points (x1, y1),
+   *                               (x2, y2) and height.
+   * @param  {array}   quadCorners An array of the quad nodes' corners.
+   * @return {array}               An array of indexes containing one to
+   *                               four integers.
+   */
+  function _quadIndexes(rectangle, quadCorners) {
+    var indexes = [];
+
+    // Iterating through quads
+    for (var i = 0; i < 4; i++)
+      if ((rectangle.x2 >= quadCorners[i][0].x) &&
+          (rectangle.x1 <= quadCorners[i][1].x) &&
+          (rectangle.y1 + rectangle.height >= quadCorners[i][0].y) &&
+          (rectangle.y1 <= quadCorners[i][2].y))
+        indexes.push(i);
+
+    return indexes;
+  }
+
+  /**
+   * Get a list of indexes of nodes containing a non-axis-aligned rectangle
+   *
+   * @param  {array}  corners      An array containing each corner of the
+   *                               rectangle defined by its coordinates (x, y).
+   * @param  {array}  quadCorners  An array of the quad nodes' corners.
+   * @return {array}               An array of indexes containing one to
+   *                               four integers.
+   */
+  function _quadCollision(corners, quadCorners) {
+    var indexes = [];
+
+    // Iterating through quads
+    for (var i = 0; i < 4; i++)
+      if (_geom.collision(corners, quadCorners[i]))
+        indexes.push(i);
+
+    return indexes;
+  }
+
+  /**
+   * Subdivide a quad by creating a node at a precise index. The function does
+   * not generate all four nodes not to potentially create unused nodes.
+   *
+   * @param  {integer}  index The index of the node to create.
+   * @param  {object}   quad  The quad object to subdivide.
+   * @return {object}         A new quad representing the node created.
+   */
+  function _quadSubdivide(index, quad) {
+    var next = quad.level + 1,
+        subw = Math.round(quad.bounds.width / 2),
+        subh = Math.round(quad.bounds.height / 2),
+        qx = Math.round(quad.bounds.x),
+        qy = Math.round(quad.bounds.y),
+        x,
+        y;
+
+    switch (index) {
+      case 0:
+        x = qx;
+        y = qy;
+        break;
+      case 1:
+        x = qx + subw;
+        y = qy;
+        break;
+      case 2:
+        x = qx;
+        y = qy + subh;
+        break;
+      case 3:
+        x = qx + subw;
+        y = qy + subh;
+        break;
+    }
+
+    return _quadTree(
+      {x: x, y: y, width: subw, height: subh},
+      next,
+      quad.maxElements,
+      quad.maxLevel
+    );
+  }
+
+  /**
+   * Recursively insert an element into the quadtree. Only points
+   * with size, i.e. axis-aligned squares, may be inserted with this
+   * method.
+   *
+   * @param  {object}  el         The element to insert in the quadtree.
+   * @param  {object}  sizedPoint A sized point defined by two top points
+   *                              (x1, y1), (x2, y2) and height.
+   * @param  {object}  quad       The quad in which to insert the element.
+   * @return {undefined}          The function does not return anything.
+   */
+  function _quadInsert(el, sizedPoint, quad) {
+    if (quad.level < quad.maxLevel) {
+
+      // Searching appropriate quads
+      var indexes = _quadIndexes(sizedPoint, quad.corners);
+
+      // Iterating
+      for (var i = 0, l = indexes.length; i < l; i++) {
+
+        // Subdividing if necessary
+        if (quad.nodes[indexes[i]] === undefined)
+          quad.nodes[indexes[i]] = _quadSubdivide(indexes[i], quad);
+
+        // Recursion
+        _quadInsert(el, sizedPoint, quad.nodes[indexes[i]]);
+      }
+    }
+    else {
+
+      // Pushing the element in a leaf node
+      quad.elements.push(el);
+    }
+  }
+
+  /**
+   * Recursively retrieve every elements held by the node containing the
+   * searched point.
+   *
+   * @param  {object}  point The searched point (x, y).
+   * @param  {object}  quad  The searched quad.
+   * @return {array}         An array of elements contained in the relevant
+   *                         node.
+   */
+  function _quadRetrievePoint(point, quad) {
+    if (quad.level < quad.maxLevel) {
+      var index = _quadIndex(point, quad.bounds);
+
+      // If node does not exist we return an empty list
+      if (quad.nodes[index] !== undefined) {
+        return _quadRetrievePoint(point, quad.nodes[index]);
+      }
+      else {
+        return [];
+      }
+    }
+    else {
+      return quad.elements;
+    }
+  }
+
+  /**
+   * Recursively retrieve every elements contained within an rectangular area
+   * that may or may not be axis-aligned.
+   *
+   * @param  {object|array} rectData       The searched area defined either by
+   *                                       an array of four corners (x, y) in
+   *                                       the case of a non-axis-aligned
+   *                                       rectangle or an object with two top
+   *                                       points (x1, y1), (x2, y2) and height.
+   * @param  {object}       quad           The searched quad.
+   * @param  {function}     collisionFunc  The collision function used to search
+   *                                       for node indexes.
+   * @param  {array?}       els            The retrieved elements.
+   * @return {array}                       An array of elements contained in the
+   *                                       area.
+   */
+  function _quadRetrieveArea(rectData, quad, collisionFunc, els) {
+    els = els || {};
+
+    if (quad.level < quad.maxLevel) {
+      var indexes = collisionFunc(rectData, quad.corners);
+
+      for (var i = 0, l = indexes.length; i < l; i++)
+        if (quad.nodes[indexes[i]] !== undefined)
+          _quadRetrieveArea(
+            rectData,
+            quad.nodes[indexes[i]],
+            collisionFunc,
+            els
+          );
+    } else
+      for (var j = 0, m = quad.elements.length; j < m; j++)
+        if (els[quad.elements[j].id] === undefined)
+          els[quad.elements[j].id] = quad.elements[j];
+
+    return els;
+  }
+
+  /**
+   * Creates the quadtree object itself.
+   *
+   * @param  {object}   bounds       The boundaries of the quad defined by an
+   *                                 origin (x, y), width and heigth.
+   * @param  {integer}  level        The level of the quad in the tree.
+   * @param  {integer}  maxElements  The max number of element in a leaf node.
+   * @param  {integer}  maxLevel     The max recursion level of the tree.
+   * @return {object}                The quadtree object.
+   */
+  function _quadTree(bounds, level, maxElements, maxLevel) {
+    return {
+      level: level || 0,
+      bounds: bounds,
+      corners: _geom.splitSquare(bounds),
+      maxElements: maxElements || 20,
+      maxLevel: maxLevel || 4,
+      elements: [],
+      nodes: []
+    };
+  }
+
+
+  /**
+   * Sigma Quad Constructor
+   * ----------------------
+   *
+   * The quad API as exposed to sigma.
+   */
+
+  /**
+   * The quad core that will become the sigma interface with the quadtree.
+   *
+   * property {object} _tree  Property holding the quadtree object.
+   * property {object} _geom  Exposition of the _geom namespace for testing.
+   * property {object} _cache Cache for the area method.
+   */
+  var quad = function() {
+    this._geom = _geom;
+    this._tree = null;
+    this._cache = {
+      query: false,
+      result: false
+    };
+  };
+
+  /**
+   * Index a graph by inserting its nodes into the quadtree.
+   *
+   * @param  {array}  nodes   An array of nodes to index.
+   * @param  {object} params  An object of parameters with at least the quad
+   *                          bounds.
+   * @return {object}         The quadtree object.
+   *
+   * Parameters:
+   * ----------
+   * bounds:      {object}   boundaries of the quad defined by its origin (x, y)
+   *                         width and heigth.
+   * prefix:      {string?}  a prefix for node geometric attributes.
+   * maxElements: {integer?} the max number of elements in a leaf node.
+   * maxLevel:    {integer?} the max recursion level of the tree.
+   */
+  quad.prototype.index = function(nodes, params) {
+
+    // Enforcing presence of boundaries
+    if (!params.bounds)
+      throw 'sigma.classes.quad.index: bounds information not given.';
+
+    // Prefix
+    var prefix = params.prefix || '';
+
+    // Building the tree
+    this._tree = _quadTree(
+      params.bounds,
+      0,
+      params.maxElements,
+      params.maxLevel
+    );
+
+    // Inserting graph nodes into the tree
+    for (var i = 0, l = nodes.length; i < l; i++) {
+
+      // Inserting node
+      _quadInsert(
+        nodes[i],
+        _geom.pointToSquare({
+          x: nodes[i][prefix + 'x'],
+          y: nodes[i][prefix + 'y'],
+          size: nodes[i][prefix + 'size']
+        }),
+        this._tree
+      );
+    }
+
+    // Reset cache:
+    this._cache = {
+      query: false,
+      result: false
+    };
+
+    // remove?
+    return this._tree;
+  };
+
+  /**
+   * Retrieve every graph nodes held by the quadtree node containing the
+   * searched point.
+   *
+   * @param  {number} x of the point.
+   * @param  {number} y of the point.
+   * @return {array}  An array of nodes retrieved.
+   */
+  quad.prototype.point = function(x, y) {
+    return this._tree ?
+      _quadRetrievePoint({x: x, y: y}, this._tree) || [] :
+      [];
+  };
+
+  /**
+   * Retrieve every graph nodes within a rectangular area. The methods keep the
+   * last area queried in cache for optimization reason and will act differently
+   * for the same reason if the area is axis-aligned or not.
+   *
+   * @param  {object} A rectangle defined by two top points (x1, y1), (x2, y2)
+   *                  and height.
+   * @return {array}  An array of nodes retrieved.
+   */
+  quad.prototype.area = function(rect) {
+    var serialized = JSON.stringify(rect),
+        collisionFunc,
+        rectData;
+
+    // Returning cache?
+    if (this._cache.query === serialized)
+      return this._cache.result;
+
+    // Axis aligned ?
+    if (_geom.isAxisAligned(rect)) {
+      collisionFunc = _quadIndexes;
+      rectData = _geom.axisAlignedTopPoints(rect);
+    }
+    else {
+      collisionFunc = _quadCollision;
+      rectData = _geom.rectangleCorners(rect);
+    }
+
+    // Retrieving nodes
+    var nodes = this._tree ?
+      _quadRetrieveArea(
+        rectData,
+        this._tree,
+        collisionFunc
+      ) :
+      [];
+
+    // Object to array
+    var nodesArray = [];
+    for (var i in nodes)
+      nodesArray.push(nodes[i]);
+
+    // Caching
+    this._cache.query = serialized;
+    this._cache.result = nodesArray;
+
+    return nodesArray;
+  };
+
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof this.sigma !== 'undefined') {
+    this.sigma.classes = this.sigma.classes || {};
+    this.sigma.classes.quad = quad;
+  } else if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = quad;
+    exports.quad = quad;
+  } else
+    this.quad = quad;
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  /**
+   * Sigma Quadtree Module for edges
+   * ===============================
+   *
+   * Author: Sébastien Heymann,
+   *   from the quad of Guillaume Plique (Yomguithereal)
+   * Version: 0.2
+   */
+
+
+
+  /**
+   * Quad Geometric Operations
+   * -------------------------
+   *
+   * A useful batch of geometric operations used by the quadtree.
+   */
+
+  var _geom = {
+
+    /**
+     * Transforms a graph node with x, y and size into an
+     * axis-aligned square.
+     *
+     * @param  {object} A graph node with at least a point (x, y) and a size.
+     * @return {object} A square: two points (x1, y1), (x2, y2) and height.
+     */
+    pointToSquare: function(n) {
+      return {
+        x1: n.x - n.size,
+        y1: n.y - n.size,
+        x2: n.x + n.size,
+        y2: n.y - n.size,
+        height: n.size * 2
+      };
+    },
+
+    /**
+     * Transforms a graph edge with x1, y1, x2, y2 and size into an
+     * axis-aligned square.
+     *
+     * @param  {object} A graph edge with at least two points
+     *                  (x1, y1), (x2, y2) and a size.
+     * @return {object} A square: two points (x1, y1), (x2, y2) and height.
+     */
+    lineToSquare: function(e) {
+      if (e.y1 < e.y2) {
+        // (e.x1, e.y1) on top
+        if (e.x1 < e.x2) {
+          // (e.x1, e.y1) on left
+          return {
+            x1: e.x1 - e.size,
+            y1: e.y1 - e.size,
+            x2: e.x2 + e.size,
+            y2: e.y1 - e.size,
+            height: e.y2 - e.y1 + e.size * 2
+          };
+        }
+        // (e.x1, e.y1) on right
+        return {
+          x1: e.x2 - e.size,
+          y1: e.y1 - e.size,
+          x2: e.x1 + e.size,
+          y2: e.y1 - e.size,
+          height: e.y2 - e.y1 + e.size * 2
+        };
+      }
+
+      // (e.x2, e.y2) on top
+      if (e.x1 < e.x2) {
+        // (e.x1, e.y1) on left
+        return {
+          x1: e.x1 - e.size,
+          y1: e.y2 - e.size,
+          x2: e.x2 + e.size,
+          y2: e.y2 - e.size,
+          height: e.y1 - e.y2 + e.size * 2
+        };
+      }
+      // (e.x2, e.y2) on right
+      return {
+        x1: e.x2 - e.size,
+        y1: e.y2 - e.size,
+        x2: e.x1 + e.size,
+        y2: e.y2 - e.size,
+        height: e.y1 - e.y2 + e.size * 2
+      };
+    },
+
+    /**
+     * Transforms a graph edge of type 'curve' with x1, y1, x2, y2,
+     * control point and size into an axis-aligned square.
+     *
+     * @param  {object} e  A graph edge with at least two points
+     *                     (x1, y1), (x2, y2) and a size.
+     * @param  {object} cp A control point (x,y).
+     * @return {object}    A square: two points (x1, y1), (x2, y2) and height.
+     */
+    quadraticCurveToSquare: function(e, cp) {
+      var pt = sigma.utils.getPointOnQuadraticCurve(
+        0.5,
+        e.x1,
+        e.y1,
+        e.x2,
+        e.y2,
+        cp.x,
+        cp.y
+      );
+
+      // Bounding box of the two points and the point at the middle of the
+      // curve:
+      var minX = Math.min(e.x1, e.x2, pt.x),
+          maxX = Math.max(e.x1, e.x2, pt.x),
+          minY = Math.min(e.y1, e.y2, pt.y),
+          maxY = Math.max(e.y1, e.y2, pt.y);
+
+      return {
+        x1: minX - e.size,
+        y1: minY - e.size,
+        x2: maxX + e.size,
+        y2: minY - e.size,
+        height: maxY - minY + e.size * 2
+      };
+    },
+
+    /**
+     * Transforms a graph self loop into an axis-aligned square.
+     *
+     * @param  {object} n A graph node with a point (x, y) and a size.
+     * @return {object}   A square: two points (x1, y1), (x2, y2) and height.
+     */
+    selfLoopToSquare: function(n) {
+      // Fitting to the curve is too costly, we compute a larger bounding box
+      // using the control points:
+      var cp = sigma.utils.getSelfLoopControlPoints(n.x, n.y, n.size);
+
+      // Bounding box of the point and the two control points:
+      var minX = Math.min(n.x, cp.x1, cp.x2),
+          maxX = Math.max(n.x, cp.x1, cp.x2),
+          minY = Math.min(n.y, cp.y1, cp.y2),
+          maxY = Math.max(n.y, cp.y1, cp.y2);
+
+      return {
+        x1: minX - n.size,
+        y1: minY - n.size,
+        x2: maxX + n.size,
+        y2: minY - n.size,
+        height: maxY - minY + n.size * 2
+      };
+    },
+
+    /**
+     * Checks whether a rectangle is axis-aligned.
+     *
+     * @param  {object}  A rectangle defined by two points
+     *                   (x1, y1) and (x2, y2).
+     * @return {boolean} True if the rectangle is axis-aligned.
+     */
+    isAxisAligned: function(r) {
+      return r.x1 === r.x2 || r.y1 === r.y2;
+    },
+
+    /**
+     * Compute top points of an axis-aligned rectangle. This is useful in
+     * cases when the rectangle has been rotated (left, right or bottom up) and
+     * later operations need to know the top points.
+     *
+     * @param  {object} An axis-aligned rectangle defined by two points
+     *                  (x1, y1), (x2, y2) and height.
+     * @return {object} A rectangle: two points (x1, y1), (x2, y2) and height.
+     */
+    axisAlignedTopPoints: function(r) {
+
+      // Basic
+      if (r.y1 === r.y2 && r.x1 < r.x2)
+        return r;
+
+      // Rotated to right
+      if (r.x1 === r.x2 && r.y2 > r.y1)
+        return {
+          x1: r.x1 - r.height, y1: r.y1,
+          x2: r.x1, y2: r.y1,
+          height: r.height
+        };
+
+      // Rotated to left
+      if (r.x1 === r.x2 && r.y2 < r.y1)
+        return {
+          x1: r.x1, y1: r.y2,
+          x2: r.x2 + r.height, y2: r.y2,
+          height: r.height
+        };
+
+      // Bottom's up
+      return {
+        x1: r.x2, y1: r.y1 - r.height,
+        x2: r.x1, y2: r.y1 - r.height,
+        height: r.height
+      };
+    },
+
+    /**
+     * Get coordinates of a rectangle's lower left corner from its top points.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @return {object} Coordinates of the corner (x, y).
+     */
+    lowerLeftCoor: function(r) {
+      var width = (
+        Math.sqrt(
+          Math.pow(r.x2 - r.x1, 2) +
+          Math.pow(r.y2 - r.y1, 2)
+        )
+      );
+
+      return {
+        x: r.x1 - (r.y2 - r.y1) * r.height / width,
+        y: r.y1 + (r.x2 - r.x1) * r.height / width
+      };
+    },
+
+    /**
+     * Get coordinates of a rectangle's lower right corner from its top points
+     * and its lower left corner.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @param  {object} A corner's coordinates (x, y).
+     * @return {object} Coordinates of the corner (x, y).
+     */
+    lowerRightCoor: function(r, llc) {
+      return {
+        x: llc.x - r.x1 + r.x2,
+        y: llc.y - r.y1 + r.y2
+      };
+    },
+
+    /**
+     * Get the coordinates of all the corners of a rectangle from its top point.
+     *
+     * @param  {object} A rectangle defined by two points (x1, y1) and (x2, y2).
+     * @return {array}  An array of the four corners' coordinates (x, y).
+     */
+    rectangleCorners: function(r) {
+      var llc = this.lowerLeftCoor(r),
+          lrc = this.lowerRightCoor(r, llc);
+
+      return [
+        {x: r.x1, y: r.y1},
+        {x: r.x2, y: r.y2},
+        {x: llc.x, y: llc.y},
+        {x: lrc.x, y: lrc.y}
+      ];
+    },
+
+    /**
+     * Split a square defined by its boundaries into four.
+     *
+     * @param  {object} Boundaries of the square (x, y, width, height).
+     * @return {array}  An array containing the four new squares, themselves
+     *                  defined by an array of their four corners (x, y).
+     */
+    splitSquare: function(b) {
+      return [
+        [
+          {x: b.x, y: b.y},
+          {x: b.x + b.width / 2, y: b.y},
+          {x: b.x, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2}
+        ],
+        [
+          {x: b.x + b.width / 2, y: b.y},
+          {x: b.x + b.width, y: b.y},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x + b.width, y: b.y + b.height / 2}
+        ],
+        [
+          {x: b.x, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x, y: b.y + b.height},
+          {x: b.x + b.width / 2, y: b.y + b.height}
+        ],
+        [
+          {x: b.x + b.width / 2, y: b.y + b.height / 2},
+          {x: b.x + b.width, y: b.y + b.height / 2},
+          {x: b.x + b.width / 2, y: b.y + b.height},
+          {x: b.x + b.width, y: b.y + b.height}
+        ]
+      ];
+    },
+
+    /**
+     * Compute the four axis between corners of rectangle A and corners of
+     * rectangle B. This is needed later to check an eventual collision.
+     *
+     * @param  {array} An array of rectangle A's four corners (x, y).
+     * @param  {array} An array of rectangle B's four corners (x, y).
+     * @return {array} An array of four axis defined by their coordinates (x,y).
+     */
+    axis: function(c1, c2) {
+      return [
+        {x: c1[1].x - c1[0].x, y: c1[1].y - c1[0].y},
+        {x: c1[1].x - c1[3].x, y: c1[1].y - c1[3].y},
+        {x: c2[0].x - c2[2].x, y: c2[0].y - c2[2].y},
+        {x: c2[0].x - c2[1].x, y: c2[0].y - c2[1].y}
+      ];
+    },
+
+    /**
+     * Project a rectangle's corner on an axis.
+     *
+     * @param  {object} Coordinates of a corner (x, y).
+     * @param  {object} Coordinates of an axis (x, y).
+     * @return {object} The projection defined by coordinates (x, y).
+     */
+    projection: function(c, a) {
+      var l = (
+        (c.x * a.x + c.y * a.y) /
+        (Math.pow(a.x, 2) + Math.pow(a.y, 2))
+      );
+
+      return {
+        x: l * a.x,
+        y: l * a.y
+      };
+    },
+
+    /**
+     * Check whether two rectangles collide on one particular axis.
+     *
+     * @param  {object}   An axis' coordinates (x, y).
+     * @param  {array}    Rectangle A's corners.
+     * @param  {array}    Rectangle B's corners.
+     * @return {boolean}  True if the rectangles collide on the axis.
+     */
+    axisCollision: function(a, c1, c2) {
+      var sc1 = [],
+          sc2 = [];
+
+      for (var ci = 0; ci < 4; ci++) {
+        var p1 = this.projection(c1[ci], a),
+            p2 = this.projection(c2[ci], a);
+
+        sc1.push(p1.x * a.x + p1.y * a.y);
+        sc2.push(p2.x * a.x + p2.y * a.y);
+      }
+
+      var maxc1 = Math.max.apply(Math, sc1),
+          maxc2 = Math.max.apply(Math, sc2),
+          minc1 = Math.min.apply(Math, sc1),
+          minc2 = Math.min.apply(Math, sc2);
+
+      return (minc2 <= maxc1 && maxc2 >= minc1);
+    },
+
+    /**
+     * Check whether two rectangles collide on each one of their four axis. If
+     * all axis collide, then the two rectangles do collide on the plane.
+     *
+     * @param  {array}    Rectangle A's corners.
+     * @param  {array}    Rectangle B's corners.
+     * @return {boolean}  True if the rectangles collide.
+     */
+    collision: function(c1, c2) {
+      var axis = this.axis(c1, c2),
+          col = true;
+
+      for (var i = 0; i < 4; i++)
+        col = col && this.axisCollision(axis[i], c1, c2);
+
+      return col;
+    }
+  };
+
+
+  /**
+   * Quad Functions
+   * ------------
+   *
+   * The Quadtree functions themselves.
+   * For each of those functions, we consider that in a splitted quad, the
+   * index of each node is the following:
+   * 0: top left
+   * 1: top right
+   * 2: bottom left
+   * 3: bottom right
+   *
+   * Moreover, the hereafter quad's philosophy is to consider that if an element
+   * collides with more than one nodes, this element belongs to each of the
+   * nodes it collides with where other would let it lie on a higher node.
+   */
+
+  /**
+   * Get the index of the node containing the point in the quad
+   *
+   * @param  {object}  point      A point defined by coordinates (x, y).
+   * @param  {object}  quadBounds Boundaries of the quad (x, y, width, heigth).
+   * @return {integer}            The index of the node containing the point.
+   */
+  function _quadIndex(point, quadBounds) {
+    var xmp = quadBounds.x + quadBounds.width / 2,
+        ymp = quadBounds.y + quadBounds.height / 2,
+        top = (point.y < ymp),
+        left = (point.x < xmp);
+
+    if (top) {
+      if (left)
+        return 0;
+      else
+        return 1;
+    }
+    else {
+      if (left)
+        return 2;
+      else
+        return 3;
+    }
+  }
+
+  /**
+   * Get a list of indexes of nodes containing an axis-aligned rectangle
+   *
+   * @param  {object}  rectangle   A rectangle defined by two points (x1, y1),
+   *                               (x2, y2) and height.
+   * @param  {array}   quadCorners An array of the quad nodes' corners.
+   * @return {array}               An array of indexes containing one to
+   *                               four integers.
+   */
+  function _quadIndexes(rectangle, quadCorners) {
+    var indexes = [];
+
+    // Iterating through quads
+    for (var i = 0; i < 4; i++)
+      if ((rectangle.x2 >= quadCorners[i][0].x) &&
+          (rectangle.x1 <= quadCorners[i][1].x) &&
+          (rectangle.y1 + rectangle.height >= quadCorners[i][0].y) &&
+          (rectangle.y1 <= quadCorners[i][2].y))
+        indexes.push(i);
+
+    return indexes;
+  }
+
+  /**
+   * Get a list of indexes of nodes containing a non-axis-aligned rectangle
+   *
+   * @param  {array}  corners      An array containing each corner of the
+   *                               rectangle defined by its coordinates (x, y).
+   * @param  {array}  quadCorners  An array of the quad nodes' corners.
+   * @return {array}               An array of indexes containing one to
+   *                               four integers.
+   */
+  function _quadCollision(corners, quadCorners) {
+    var indexes = [];
+
+    // Iterating through quads
+    for (var i = 0; i < 4; i++)
+      if (_geom.collision(corners, quadCorners[i]))
+        indexes.push(i);
+
+    return indexes;
+  }
+
+  /**
+   * Subdivide a quad by creating a node at a precise index. The function does
+   * not generate all four nodes not to potentially create unused nodes.
+   *
+   * @param  {integer}  index The index of the node to create.
+   * @param  {object}   quad  The quad object to subdivide.
+   * @return {object}         A new quad representing the node created.
+   */
+  function _quadSubdivide(index, quad) {
+    var next = quad.level + 1,
+        subw = Math.round(quad.bounds.width / 2),
+        subh = Math.round(quad.bounds.height / 2),
+        qx = Math.round(quad.bounds.x),
+        qy = Math.round(quad.bounds.y),
+        x,
+        y;
+
+    switch (index) {
+      case 0:
+        x = qx;
+        y = qy;
+        break;
+      case 1:
+        x = qx + subw;
+        y = qy;
+        break;
+      case 2:
+        x = qx;
+        y = qy + subh;
+        break;
+      case 3:
+        x = qx + subw;
+        y = qy + subh;
+        break;
+    }
+
+    return _quadTree(
+      {x: x, y: y, width: subw, height: subh},
+      next,
+      quad.maxElements,
+      quad.maxLevel
+    );
+  }
+
+  /**
+   * Recursively insert an element into the quadtree. Only points
+   * with size, i.e. axis-aligned squares, may be inserted with this
+   * method.
+   *
+   * @param  {object}  el         The element to insert in the quadtree.
+   * @param  {object}  sizedPoint A sized point defined by two top points
+   *                              (x1, y1), (x2, y2) and height.
+   * @param  {object}  quad       The quad in which to insert the element.
+   * @return {undefined}          The function does not return anything.
+   */
+  function _quadInsert(el, sizedPoint, quad) {
+    if (quad.level < quad.maxLevel) {
+
+      // Searching appropriate quads
+      var indexes = _quadIndexes(sizedPoint, quad.corners);
+
+      // Iterating
+      for (var i = 0, l = indexes.length; i < l; i++) {
+
+        // Subdividing if necessary
+        if (quad.nodes[indexes[i]] === undefined)
+          quad.nodes[indexes[i]] = _quadSubdivide(indexes[i], quad);
+
+        // Recursion
+        _quadInsert(el, sizedPoint, quad.nodes[indexes[i]]);
+      }
+    }
+    else {
+
+      // Pushing the element in a leaf node
+      quad.elements.push(el);
+    }
+  }
+
+  /**
+   * Recursively retrieve every elements held by the node containing the
+   * searched point.
+   *
+   * @param  {object}  point The searched point (x, y).
+   * @param  {object}  quad  The searched quad.
+   * @return {array}         An array of elements contained in the relevant
+   *                         node.
+   */
+  function _quadRetrievePoint(point, quad) {
+    if (quad.level < quad.maxLevel) {
+      var index = _quadIndex(point, quad.bounds);
+
+      // If node does not exist we return an empty list
+      if (quad.nodes[index] !== undefined) {
+        return _quadRetrievePoint(point, quad.nodes[index]);
+      }
+      else {
+        return [];
+      }
+    }
+    else {
+      return quad.elements;
+    }
+  }
+
+  /**
+   * Recursively retrieve every elements contained within an rectangular area
+   * that may or may not be axis-aligned.
+   *
+   * @param  {object|array} rectData       The searched area defined either by
+   *                                       an array of four corners (x, y) in
+   *                                       the case of a non-axis-aligned
+   *                                       rectangle or an object with two top
+   *                                       points (x1, y1), (x2, y2) and height.
+   * @param  {object}       quad           The searched quad.
+   * @param  {function}     collisionFunc  The collision function used to search
+   *                                       for node indexes.
+   * @param  {array?}       els            The retrieved elements.
+   * @return {array}                       An array of elements contained in the
+   *                                       area.
+   */
+  function _quadRetrieveArea(rectData, quad, collisionFunc, els) {
+    els = els || {};
+
+    if (quad.level < quad.maxLevel) {
+      var indexes = collisionFunc(rectData, quad.corners);
+
+      for (var i = 0, l = indexes.length; i < l; i++)
+        if (quad.nodes[indexes[i]] !== undefined)
+          _quadRetrieveArea(
+            rectData,
+            quad.nodes[indexes[i]],
+            collisionFunc,
+            els
+          );
+    } else
+      for (var j = 0, m = quad.elements.length; j < m; j++)
+        if (els[quad.elements[j].id] === undefined)
+          els[quad.elements[j].id] = quad.elements[j];
+
+    return els;
+  }
+
+  /**
+   * Creates the quadtree object itself.
+   *
+   * @param  {object}   bounds       The boundaries of the quad defined by an
+   *                                 origin (x, y), width and heigth.
+   * @param  {integer}  level        The level of the quad in the tree.
+   * @param  {integer}  maxElements  The max number of element in a leaf node.
+   * @param  {integer}  maxLevel     The max recursion level of the tree.
+   * @return {object}                The quadtree object.
+   */
+  function _quadTree(bounds, level, maxElements, maxLevel) {
+    return {
+      level: level || 0,
+      bounds: bounds,
+      corners: _geom.splitSquare(bounds),
+      maxElements: maxElements || 40,
+      maxLevel: maxLevel || 8,
+      elements: [],
+      nodes: []
+    };
+  }
+
+
+  /**
+   * Sigma Quad Constructor
+   * ----------------------
+   *
+   * The edgequad API as exposed to sigma.
+   */
+
+  /**
+   * The edgequad core that will become the sigma interface with the quadtree.
+   *
+   * property {object} _tree     Property holding the quadtree object.
+   * property {object} _geom     Exposition of the _geom namespace for testing.
+   * property {object} _cache    Cache for the area method.
+   * property {boolean} _enabled Can index and retreive elements.
+   */
+  var edgequad = function() {
+    this._geom = _geom;
+    this._tree = null;
+    this._cache = {
+      query: false,
+      result: false
+    };
+    this._enabled = true;
+  };
+
+  /**
+   * Index a graph by inserting its edges into the quadtree.
+   *
+   * @param  {object} graph   A graph instance.
+   * @param  {object} params  An object of parameters with at least the quad
+   *                          bounds.
+   * @return {object}         The quadtree object.
+   *
+   * Parameters:
+   * ----------
+   * bounds:      {object}   boundaries of the quad defined by its origin (x, y)
+   *                         width and heigth.
+   * prefix:      {string?}  a prefix for edge geometric attributes.
+   * maxElements: {integer?} the max number of elements in a leaf node.
+   * maxLevel:    {integer?} the max recursion level of the tree.
+   */
+  edgequad.prototype.index = function(graph, params) {
+    if (!this._enabled)
+      return this._tree;
+
+    // Enforcing presence of boundaries
+    if (!params.bounds)
+      throw 'sigma.classes.edgequad.index: bounds information not given.';
+
+    // Prefix
+    var prefix = params.prefix || '',
+        cp,
+        source,
+        target,
+        n,
+        e;
+
+    // Building the tree
+    this._tree = _quadTree(
+      params.bounds,
+      0,
+      params.maxElements,
+      params.maxLevel
+    );
+
+    var edges = graph.edges();
+
+    // Inserting graph edges into the tree
+    for (var i = 0, l = edges.length; i < l; i++) {
+      source = graph.nodes(edges[i].source);
+      target = graph.nodes(edges[i].target);
+      e = {
+        x1: source[prefix + 'x'],
+        y1: source[prefix + 'y'],
+        x2: target[prefix + 'x'],
+        y2: target[prefix + 'y'],
+        size: edges[i][prefix + 'size'] || 0
+      };
+
+      // Inserting edge
+      if (edges[i].type === 'curve' || edges[i].type === 'curvedArrow') {
+        if (source.id === target.id) {
+          n = {
+            x: source[prefix + 'x'],
+            y: source[prefix + 'y'],
+            size: source[prefix + 'size'] || 0
+          };
+          _quadInsert(
+            edges[i],
+            _geom.selfLoopToSquare(n),
+            this._tree);
+        }
+        else {
+          cp = sigma.utils.getQuadraticControlPoint(e.x1, e.y1, e.x2, e.y2);
+          _quadInsert(
+            edges[i],
+            _geom.quadraticCurveToSquare(e, cp),
+            this._tree);
+        }
+      }
+      else {
+        _quadInsert(
+          edges[i],
+          _geom.lineToSquare(e),
+          this._tree);
+      }
+    }
+
+    // Reset cache:
+    this._cache = {
+      query: false,
+      result: false
+    };
+
+    // remove?
+    return this._tree;
+  };
+
+  /**
+   * Retrieve every graph edges held by the quadtree node containing the
+   * searched point.
+   *
+   * @param  {number} x of the point.
+   * @param  {number} y of the point.
+   * @return {array}  An array of edges retrieved.
+   */
+  edgequad.prototype.point = function(x, y) {
+    if (!this._enabled)
+      return [];
+
+    return this._tree ?
+      _quadRetrievePoint({x: x, y: y}, this._tree) || [] :
+      [];
+  };
+
+  /**
+   * Retrieve every graph edges within a rectangular area. The methods keep the
+   * last area queried in cache for optimization reason and will act differently
+   * for the same reason if the area is axis-aligned or not.
+   *
+   * @param  {object} A rectangle defined by two top points (x1, y1), (x2, y2)
+   *                  and height.
+   * @return {array}  An array of edges retrieved.
+   */
+  edgequad.prototype.area = function(rect) {
+    if (!this._enabled)
+      return [];
+
+    var serialized = JSON.stringify(rect),
+        collisionFunc,
+        rectData;
+
+    // Returning cache?
+    if (this._cache.query === serialized)
+      return this._cache.result;
+
+    // Axis aligned ?
+    if (_geom.isAxisAligned(rect)) {
+      collisionFunc = _quadIndexes;
+      rectData = _geom.axisAlignedTopPoints(rect);
+    }
+    else {
+      collisionFunc = _quadCollision;
+      rectData = _geom.rectangleCorners(rect);
+    }
+
+    // Retrieving edges
+    var edges = this._tree ?
+      _quadRetrieveArea(
+        rectData,
+        this._tree,
+        collisionFunc
+      ) :
+      [];
+
+    // Object to array
+    var edgesArray = [];
+    for (var i in edges)
+      edgesArray.push(edges[i]);
+
+    // Caching
+    this._cache.query = serialized;
+    this._cache.result = edgesArray;
+
+    return edgesArray;
+  };
+
+
+  /**
+   * EXPORT:
+   * *******
+   */
+  if (typeof this.sigma !== 'undefined') {
+    this.sigma.classes = this.sigma.classes || {};
+    this.sigma.classes.edgequad = edgequad;
+  } else if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports)
+      exports = module.exports = edgequad;
+    exports.edgequad = edgequad;
+  } else
+    this.edgequad = edgequad;
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.captors');
+
+  /**
+   * The user inputs default captor. It deals with mouse events, keyboards
+   * events and touch events.
+   *
+   * @param  {DOMElement}   target   The DOM element where the listeners will be
+   *                                 bound.
+   * @param  {camera}       camera   The camera related to the target.
+   * @param  {configurable} settings The settings function.
+   * @return {sigma.captor}          The fresh new captor instance.
+   */
+  sigma.captors.mouse = function(target, camera, settings) {
+    var _self = this,
+        _target = target,
+        _camera = camera,
+        _settings = settings,
+
+        // CAMERA MANAGEMENT:
+        // ******************
+        // The camera position when the user starts dragging:
+        _startCameraX,
+        _startCameraY,
+        _startCameraAngle,
+
+        // The latest stage position:
+        _lastCameraX,
+        _lastCameraY,
+        _lastCameraAngle,
+        _lastCameraRatio,
+
+        // MOUSE MANAGEMENT:
+        // *****************
+        // The mouse position when the user starts dragging:
+        _startMouseX,
+        _startMouseY,
+
+        _isMouseDown,
+        _isMoving,
+        _hasDragged,
+        _downStartTime,
+        _movingTimeoutId;
+
+    sigma.classes.dispatcher.extend(this);
+
+    sigma.utils.doubleClick(_target, 'click', _doubleClickHandler);
+    _target.addEventListener('DOMMouseScroll', _wheelHandler, false);
+    _target.addEventListener('mousewheel', _wheelHandler, false);
+    _target.addEventListener('mousemove', _moveHandler, false);
+    _target.addEventListener('mousedown', _downHandler, false);
+    _target.addEventListener('click', _clickHandler, false);
+    _target.addEventListener('mouseout', _outHandler, false);
+    document.addEventListener('mouseup', _upHandler, false);
+
+
+
+
+    /**
+     * This method unbinds every handlers that makes the captor work.
+     */
+    this.kill = function() {
+      sigma.utils.unbindDoubleClick(_target, 'click');
+      _target.removeEventListener('DOMMouseScroll', _wheelHandler);
+      _target.removeEventListener('mousewheel', _wheelHandler);
+      _target.removeEventListener('mousemove', _moveHandler);
+      _target.removeEventListener('mousedown', _downHandler);
+      _target.removeEventListener('click', _clickHandler);
+      _target.removeEventListener('mouseout', _outHandler);
+      document.removeEventListener('mouseup', _upHandler);
+    };
+
+
+
+
+    // MOUSE EVENTS:
+    // *************
+
+    /**
+     * The handler listening to the 'move' mouse event. It will effectively
+     * drag the graph.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _moveHandler(e) {
+      var x,
+          y,
+          pos;
+
+      // Dispatch event:
+      if (_settings('mouseEnabled')) {
+        _self.dispatchEvent('mousemove',
+          sigma.utils.mouseCoords(e));
+
+        if (_isMouseDown) {
+          _isMoving = true;
+          _hasDragged = true;
+
+          if (_movingTimeoutId)
+            clearTimeout(_movingTimeoutId);
+
+          _movingTimeoutId = setTimeout(function() {
+            _isMoving = false;
+          }, _settings('dragTimeout'));
+
+          sigma.misc.animation.killAll(_camera);
+
+          _camera.isMoving = true;
+          pos = _camera.cameraPosition(
+            sigma.utils.getX(e) - _startMouseX,
+            sigma.utils.getY(e) - _startMouseY,
+            true
+          );
+
+          x = _startCameraX - pos.x;
+          y = _startCameraY - pos.y;
+
+          if (x !== _camera.x || y !== _camera.y) {
+            _lastCameraX = _camera.x;
+            _lastCameraY = _camera.y;
+
+            _camera.goTo({
+              x: x,
+              y: y
+            });
+          }
+
+          if (e.preventDefault)
+            e.preventDefault();
+          else
+            e.returnValue = false;
+
+          e.stopPropagation();
+          return false;
+        }
+      }
+    }
+
+    /**
+     * The handler listening to the 'up' mouse event. It will stop dragging the
+     * graph.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _upHandler(e) {
+      if (_settings('mouseEnabled') && _isMouseDown) {
+        _isMouseDown = false;
+        if (_movingTimeoutId)
+          clearTimeout(_movingTimeoutId);
+
+        _camera.isMoving = false;
+
+        var x = sigma.utils.getX(e),
+            y = sigma.utils.getY(e);
+
+        if (_isMoving) {
+          sigma.misc.animation.killAll(_camera);
+          sigma.misc.animation.camera(
+            _camera,
+            {
+              x: _camera.x +
+                _settings('mouseInertiaRatio') * (_camera.x - _lastCameraX),
+              y: _camera.y +
+                _settings('mouseInertiaRatio') * (_camera.y - _lastCameraY)
+            },
+            {
+              easing: 'quadraticOut',
+              duration: _settings('mouseInertiaDuration')
+            }
+          );
+        } else if (
+          _startMouseX !== x ||
+          _startMouseY !== y
+        )
+          _camera.goTo({
+            x: _camera.x,
+            y: _camera.y
+          });
+
+        _self.dispatchEvent('mouseup',
+          sigma.utils.mouseCoords(e));
+
+        // Update _isMoving flag:
+        _isMoving = false;
+      }
+    }
+
+    /**
+     * The handler listening to the 'down' mouse event. It will start observing
+     * the mouse position for dragging the graph.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _downHandler(e) {
+      if (_settings('mouseEnabled')) {
+        _startCameraX = _camera.x;
+        _startCameraY = _camera.y;
+
+        _lastCameraX = _camera.x;
+        _lastCameraY = _camera.y;
+
+        _startMouseX = sigma.utils.getX(e);
+        _startMouseY = sigma.utils.getY(e);
+
+        _hasDragged = false;
+        _downStartTime = (new Date()).getTime();
+
+        switch (e.which) {
+          case 2:
+            // Middle mouse button pressed
+            // Do nothing.
+            break;
+          case 3:
+            // Right mouse button pressed
+            _self.dispatchEvent('rightclick',
+              sigma.utils.mouseCoords(e, _startMouseX, _startMouseY));
+            break;
+          // case 1:
+          default:
+            // Left mouse button pressed
+            _isMouseDown = true;
+
+            _self.dispatchEvent('mousedown',
+              sigma.utils.mouseCoords(e, _startMouseX, _startMouseY));
+        }
+      }
+    }
+
+    /**
+     * The handler listening to the 'out' mouse event. It will just redispatch
+     * the event.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _outHandler(e) {
+      if (_settings('mouseEnabled'))
+        _self.dispatchEvent('mouseout');
+    }
+
+    /**
+     * The handler listening to the 'click' mouse event. It will redispatch the
+     * click event, but with normalized X and Y coordinates.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _clickHandler(e) {
+      if (_settings('mouseEnabled')) {
+        var event = sigma.utils.mouseCoords(e);
+        event.isDragging =
+          (((new Date()).getTime() - _downStartTime) > 100) && _hasDragged;
+        _self.dispatchEvent('click', event);
+      }
+
+      if (e.preventDefault)
+        e.preventDefault();
+      else
+        e.returnValue = false;
+
+      e.stopPropagation();
+      return false;
+    }
+
+    /**
+     * The handler listening to the double click custom event. It will
+     * basically zoom into the graph.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _doubleClickHandler(e) {
+      var pos,
+          ratio,
+          animation;
+
+      if (_settings('mouseEnabled')) {
+        ratio = 1 / _settings('doubleClickZoomingRatio');
+
+        _self.dispatchEvent('doubleclick',
+            sigma.utils.mouseCoords(e, _startMouseX, _startMouseY));
+
+        if (_settings('doubleClickEnabled')) {
+          pos = _camera.cameraPosition(
+            sigma.utils.getX(e) - sigma.utils.getCenter(e).x,
+            sigma.utils.getY(e) - sigma.utils.getCenter(e).y,
+            true
+          );
+
+          animation = {
+            duration: _settings('doubleClickZoomDuration')
+          };
+
+          sigma.utils.zoomTo(_camera, pos.x, pos.y, ratio, animation);
+        }
+
+        if (e.preventDefault)
+          e.preventDefault();
+        else
+          e.returnValue = false;
+
+        e.stopPropagation();
+        return false;
+      }
+    }
+
+    /**
+     * The handler listening to the 'wheel' mouse event. It will basically zoom
+     * in or not into the graph.
+     *
+     * @param {event} e A mouse event.
+     */
+    function _wheelHandler(e) {
+      var pos,
+          ratio,
+          animation;
+
+      if (_settings('mouseEnabled') && _settings('mouseWheelEnabled')) {
+        ratio = sigma.utils.getDelta(e) > 0 ?
+          1 / _settings('zoomingRatio') :
+          _settings('zoomingRatio');
+
+        pos = _camera.cameraPosition(
+          sigma.utils.getX(e) - sigma.utils.getCenter(e).x,
+          sigma.utils.getY(e) - sigma.utils.getCenter(e).y,
+          true
+        );
+
+        animation = {
+          duration: _settings('mouseZoomDuration')
+        };
+
+        sigma.utils.zoomTo(_camera, pos.x, pos.y, ratio, animation);
+
+        if (e.preventDefault)
+          e.preventDefault();
+        else
+          e.returnValue = false;
+
+        e.stopPropagation();
+        return false;
+      }
+    }
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.captors');
+
+  /**
+   * The user inputs default captor. It deals with mouse events, keyboards
+   * events and touch events.
+   *
+   * @param  {DOMElement}   target   The DOM element where the listeners will be
+   *                                 bound.
+   * @param  {camera}       camera   The camera related to the target.
+   * @param  {configurable} settings The settings function.
+   * @return {sigma.captor}          The fresh new captor instance.
+   */
+  sigma.captors.touch = function(target, camera, settings) {
+    var _self = this,
+        _target = target,
+        _camera = camera,
+        _settings = settings,
+
+        // CAMERA MANAGEMENT:
+        // ******************
+        // The camera position when the user starts dragging:
+        _startCameraX,
+        _startCameraY,
+        _startCameraAngle,
+        _startCameraRatio,
+
+        // The latest stage position:
+        _lastCameraX,
+        _lastCameraY,
+        _lastCameraAngle,
+        _lastCameraRatio,
+
+        // TOUCH MANAGEMENT:
+        // *****************
+        // Touches that are down:
+        _downTouches = [],
+
+        _startTouchX0,
+        _startTouchY0,
+        _startTouchX1,
+        _startTouchY1,
+        _startTouchAngle,
+        _startTouchDistance,
+
+        _touchMode,
+
+        _isMoving,
+        _doubleTap,
+        _movingTimeoutId;
+
+    sigma.classes.dispatcher.extend(this);
+
+    sigma.utils.doubleClick(_target, 'touchstart', _doubleTapHandler);
+    _target.addEventListener('touchstart', _handleStart, false);
+    _target.addEventListener('touchend', _handleLeave, false);
+    _target.addEventListener('touchcancel', _handleLeave, false);
+    _target.addEventListener('touchleave', _handleLeave, false);
+    _target.addEventListener('touchmove', _handleMove, false);
+
+    function position(e) {
+      var offset = sigma.utils.getOffset(_target);
+
+      return {
+        x: e.pageX - offset.left,
+        y: e.pageY - offset.top
+      };
+    }
+
+    /**
+     * This method unbinds every handlers that makes the captor work.
+     */
+    this.kill = function() {
+      sigma.utils.unbindDoubleClick(_target, 'touchstart');
+      _target.addEventListener('touchstart', _handleStart);
+      _target.addEventListener('touchend', _handleLeave);
+      _target.addEventListener('touchcancel', _handleLeave);
+      _target.addEventListener('touchleave', _handleLeave);
+      _target.addEventListener('touchmove', _handleMove);
+    };
+
+    // TOUCH EVENTS:
+    // *************
+    /**
+     * The handler listening to the 'touchstart' event. It will set the touch
+     * mode ("_touchMode") and start observing the user touch moves.
+     *
+     * @param {event} e A touch event.
+     */
+    function _handleStart(e) {
+      if (_settings('touchEnabled')) {
+        var x0,
+            x1,
+            y0,
+            y1,
+            pos0,
+            pos1;
+
+        _downTouches = e.touches;
+
+        switch (_downTouches.length) {
+          case 1:
+            _camera.isMoving = true;
+            _touchMode = 1;
+
+            _startCameraX = _camera.x;
+            _startCameraY = _camera.y;
+
+            _lastCameraX = _camera.x;
+            _lastCameraY = _camera.y;
+
+            pos0 = position(_downTouches[0]);
+            _startTouchX0 = pos0.x;
+            _startTouchY0 = pos0.y;
+
+            break;
+          case 2:
+            _camera.isMoving = true;
+            _touchMode = 2;
+
+            pos0 = position(_downTouches[0]);
+            pos1 = position(_downTouches[1]);
+            x0 = pos0.x;
+            y0 = pos0.y;
+            x1 = pos1.x;
+            y1 = pos1.y;
+
+            _lastCameraX = _camera.x;
+            _lastCameraY = _camera.y;
+
+            _startCameraAngle = _camera.angle;
+            _startCameraRatio = _camera.ratio;
+
+            _startCameraX = _camera.x;
+            _startCameraY = _camera.y;
+
+            _startTouchX0 = x0;
+            _startTouchY0 = y0;
+            _startTouchX1 = x1;
+            _startTouchY1 = y1;
+
+            _startTouchAngle = Math.atan2(
+              _startTouchY1 - _startTouchY0,
+              _startTouchX1 - _startTouchX0
+            );
+            _startTouchDistance = Math.sqrt(
+              (_startTouchY1 - _startTouchY0) *
+                (_startTouchY1 - _startTouchY0) +
+              (_startTouchX1 - _startTouchX0) *
+                (_startTouchX1 - _startTouchX0)
+            );
+
+            e.preventDefault();
+            return false;
+        }
+      }
+    }
+
+    /**
+     * The handler listening to the 'touchend', 'touchcancel' and 'touchleave'
+     * event. It will update the touch mode if there are still at least one
+     * finger, and stop dragging else.
+     *
+     * @param {event} e A touch event.
+     */
+    function _handleLeave(e) {
+      if (_settings('touchEnabled')) {
+        _downTouches = e.touches;
+        var inertiaRatio = _settings('touchInertiaRatio');
+
+        if (_movingTimeoutId) {
+          _isMoving = false;
+          clearTimeout(_movingTimeoutId);
+        }
+
+        switch (_touchMode) {
+          case 2:
+            if (e.touches.length === 1) {
+              _handleStart(e);
+
+              e.preventDefault();
+              break;
+            }
+            /* falls through */
+          case 1:
+            _camera.isMoving = false;
+            _self.dispatchEvent('stopDrag');
+
+            if (_isMoving) {
+              _doubleTap = false;
+              sigma.misc.animation.camera(
+                _camera,
+                {
+                  x: _camera.x +
+                    inertiaRatio * (_camera.x - _lastCameraX),
+                  y: _camera.y +
+                    inertiaRatio * (_camera.y - _lastCameraY)
+                },
+                {
+                  easing: 'quadraticOut',
+                  duration: _settings('touchInertiaDuration')
+                }
+              );
+            }
+
+            _isMoving = false;
+            _touchMode = 0;
+            break;
+        }
+      }
+    }
+
+    /**
+     * The handler listening to the 'touchmove' event. It will effectively drag
+     * the graph, and eventually zooms and turn it if the user is using two
+     * fingers.
+     *
+     * @param {event} e A touch event.
+     */
+    function _handleMove(e) {
+      if (!_doubleTap && _settings('touchEnabled')) {
+        var x0,
+            x1,
+            y0,
+            y1,
+            cos,
+            sin,
+            end,
+            pos0,
+            pos1,
+            diff,
+            start,
+            dAngle,
+            dRatio,
+            newStageX,
+            newStageY,
+            newStageRatio,
+            newStageAngle;
+
+        _downTouches = e.touches;
+        _isMoving = true;
+
+        if (_movingTimeoutId)
+          clearTimeout(_movingTimeoutId);
+
+        _movingTimeoutId = setTimeout(function() {
+          _isMoving = false;
+        }, _settings('dragTimeout'));
+
+        switch (_touchMode) {
+          case 1:
+            pos0 = position(_downTouches[0]);
+            x0 = pos0.x;
+            y0 = pos0.y;
+
+            diff = _camera.cameraPosition(
+              x0 - _startTouchX0,
+              y0 - _startTouchY0,
+              true
+            );
+
+            newStageX = _startCameraX - diff.x;
+            newStageY = _startCameraY - diff.y;
+
+            if (newStageX !== _camera.x || newStageY !== _camera.y) {
+              _lastCameraX = _camera.x;
+              _lastCameraY = _camera.y;
+
+              _camera.goTo({
+                x: newStageX,
+                y: newStageY
+              });
+
+              _self.dispatchEvent('mousemove',
+                sigma.utils.mouseCoords(e, pos0.x, pos0.y));
+
+              _self.dispatchEvent('drag');
+            }
+            break;
+          case 2:
+            pos0 = position(_downTouches[0]);
+            pos1 = position(_downTouches[1]);
+            x0 = pos0.x;
+            y0 = pos0.y;
+            x1 = pos1.x;
+            y1 = pos1.y;
+
+            start = _camera.cameraPosition(
+              (_startTouchX0 + _startTouchX1) / 2 -
+                sigma.utils.getCenter(e).x,
+              (_startTouchY0 + _startTouchY1) / 2 -
+                sigma.utils.getCenter(e).y,
+              true
+            );
+            end = _camera.cameraPosition(
+              (x0 + x1) / 2 - sigma.utils.getCenter(e).x,
+              (y0 + y1) / 2 - sigma.utils.getCenter(e).y,
+              true
+            );
+
+            dAngle = Math.atan2(y1 - y0, x1 - x0) - _startTouchAngle;
+            dRatio = Math.sqrt(
+              (y1 - y0) * (y1 - y0) + (x1 - x0) * (x1 - x0)
+            ) / _startTouchDistance;
+
+            // Translation:
+            x0 = start.x;
+            y0 = start.y;
+
+            // Homothetic transformation:
+            newStageRatio = _startCameraRatio / dRatio;
+            x0 = x0 * dRatio;
+            y0 = y0 * dRatio;
+
+            // Rotation:
+            newStageAngle = _startCameraAngle - dAngle;
+            cos = Math.cos(-dAngle);
+            sin = Math.sin(-dAngle);
+            x1 = x0 * cos + y0 * sin;
+            y1 = y0 * cos - x0 * sin;
+            x0 = x1;
+            y0 = y1;
+
+            // Finalize:
+            newStageX = x0 - end.x + _startCameraX;
+            newStageY = y0 - end.y + _startCameraY;
+
+            if (
+              newStageRatio !== _camera.ratio ||
+              newStageAngle !== _camera.angle ||
+              newStageX !== _camera.x ||
+              newStageY !== _camera.y
+            ) {
+              _lastCameraX = _camera.x;
+              _lastCameraY = _camera.y;
+              _lastCameraAngle = _camera.angle;
+              _lastCameraRatio = _camera.ratio;
+
+              _camera.goTo({
+                x: newStageX,
+                y: newStageY,
+                angle: newStageAngle,
+                ratio: newStageRatio
+              });
+
+              _self.dispatchEvent('drag');
+            }
+
+            break;
+        }
+
+        e.preventDefault();
+        return false;
+      }
+    }
+
+    /**
+     * The handler listening to the double tap custom event. It will
+     * basically zoom into the graph.
+     *
+     * @param {event} e A touch event.
+     */
+    function _doubleTapHandler(e) {
+      var pos,
+          ratio,
+          animation;
+
+      if (e.touches && e.touches.length === 1 && _settings('touchEnabled')) {
+        _doubleTap = true;
+
+        ratio = 1 / _settings('doubleClickZoomingRatio');
+
+        pos = position(e.touches[0]);
+        _self.dispatchEvent('doubleclick',
+          sigma.utils.mouseCoords(e, pos.x, pos.y));
+
+        if (_settings('doubleClickEnabled')) {
+          pos = _camera.cameraPosition(
+            pos.x - sigma.utils.getCenter(e).x,
+            pos.y - sigma.utils.getCenter(e).y,
+            true
+          );
+
+          animation = {
+            duration: _settings('doubleClickZoomDuration'),
+            onComplete: function() {
+              _doubleTap = false;
+            }
+          };
+
+          sigma.utils.zoomTo(_camera, pos.x, pos.y, ratio, animation);
+        }
+
+        if (e.preventDefault)
+          e.preventDefault();
+        else
+          e.returnValue = false;
+
+        e.stopPropagation();
+        return false;
+      }
+    }
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  if (typeof conrad === 'undefined')
+    throw 'conrad is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.renderers');
+
+  /**
+   * This function is the constructor of the canvas sigma's renderer.
+   *
+   * @param  {sigma.classes.graph}            graph    The graph to render.
+   * @param  {sigma.classes.camera}           camera   The camera.
+   * @param  {configurable}           settings The sigma instance settings
+   *                                           function.
+   * @param  {object}                 object   The options object.
+   * @return {sigma.renderers.canvas}          The renderer instance.
+   */
+  sigma.renderers.canvas = function(graph, camera, settings, options) {
+    if (typeof options !== 'object')
+      throw 'sigma.renderers.canvas: Wrong arguments.';
+
+    if (!(options.container instanceof HTMLElement))
+      throw 'Container not found.';
+
+    var k,
+        i,
+        l,
+        a,
+        fn,
+        self = this;
+
+    sigma.classes.dispatcher.extend(this);
+
+    // Initialize main attributes:
+    Object.defineProperty(this, 'conradId', {
+      value: sigma.utils.id()
+    });
+    this.graph = graph;
+    this.camera = camera;
+    this.contexts = {};
+    this.domElements = {};
+    this.options = options;
+    this.container = this.options.container;
+    this.settings = (
+        typeof options.settings === 'object' &&
+        options.settings
+      ) ?
+        settings.embedObjects(options.settings) :
+        settings;
+
+    // Node indexes:
+    this.nodesOnScreen = [];
+    this.edgesOnScreen = [];
+
+    // Conrad related attributes:
+    this.jobs = {};
+
+    // Find the prefix:
+    this.options.prefix = 'renderer' + this.conradId + ':';
+
+    // Initialize the DOM elements:
+    if (
+      !this.settings('batchEdgesDrawing')
+    ) {
+      this.initDOM('canvas', 'scene');
+      this.contexts.edges = this.contexts.scene;
+      this.contexts.nodes = this.contexts.scene;
+      this.contexts.labels = this.contexts.scene;
+    } else {
+      this.initDOM('canvas', 'edges');
+      this.initDOM('canvas', 'scene');
+      this.contexts.nodes = this.contexts.scene;
+      this.contexts.labels = this.contexts.scene;
+    }
+
+    this.initDOM('canvas', 'mouse');
+    this.contexts.hover = this.contexts.mouse;
+
+    // Initialize captors:
+    this.captors = [];
+    a = this.options.captors || [sigma.captors.mouse, sigma.captors.touch];
+    for (i = 0, l = a.length; i < l; i++) {
+      fn = typeof a[i] === 'function' ? a[i] : sigma.captors[a[i]];
+      this.captors.push(
+        new fn(
+          this.domElements.mouse,
+          this.camera,
+          this.settings
+        )
+      );
+    }
+
+    // Deal with sigma events:
+    sigma.misc.bindEvents.call(this, this.options.prefix);
+    sigma.misc.drawHovers.call(this, this.options.prefix);
+
+    this.resize(false);
+  };
+
+
+
+
+  /**
+   * This method renders the graph on the canvases.
+   *
+   * @param  {?object}                options Eventually an object of options.
+   * @return {sigma.renderers.canvas}         Returns the instance itself.
+   */
+  sigma.renderers.canvas.prototype.render = function(options) {
+    options = options || {};
+
+    var a,
+        i,
+        k,
+        l,
+        o,
+        id,
+        end,
+        job,
+        start,
+        edges,
+        renderers,
+        rendererType,
+        batchSize,
+        tempGCO,
+        index = {},
+        graph = this.graph,
+        nodes = this.graph.nodes,
+        prefix = this.options.prefix || '',
+        drawEdges = this.settings(options, 'drawEdges'),
+        drawNodes = this.settings(options, 'drawNodes'),
+        drawLabels = this.settings(options, 'drawLabels'),
+        drawEdgeLabels = this.settings(options, 'drawEdgeLabels'),
+        embedSettings = this.settings.embedObjects(options, {
+          prefix: this.options.prefix
+        });
+
+    // Call the resize function:
+    this.resize(false);
+
+    // Check the 'hideEdgesOnMove' setting:
+    if (this.settings(options, 'hideEdgesOnMove'))
+      if (this.camera.isAnimated || this.camera.isMoving)
+        drawEdges = false;
+
+    // Apply the camera's view:
+    this.camera.applyView(
+      undefined,
+      this.options.prefix,
+      {
+        width: this.width,
+        height: this.height
+      }
+    );
+
+    // Clear canvases:
+    this.clear();
+
+    // Kill running jobs:
+    for (k in this.jobs)
+      if (conrad.hasJob(k))
+        conrad.killJob(k);
+
+    // Find which nodes are on screen:
+    this.edgesOnScreen = [];
+    this.nodesOnScreen = this.camera.quadtree.area(
+      this.camera.getRectangle(this.width, this.height)
+    );
+
+    for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++)
+      index[a[i].id] = a[i];
+
+    // Draw edges:
+    // - If settings('batchEdgesDrawing') is true, the edges are displayed per
+    //   batches. If not, they are drawn in one frame.
+    if (drawEdges) {
+      // First, let's identify which edges to draw. To do this, we just keep
+      // every edges that have at least one extremity displayed according to
+      // the quadtree and the "hidden" attribute. We also do not keep hidden
+      // edges.
+      for (a = graph.edges(), i = 0, l = a.length; i < l; i++) {
+        o = a[i];
+        if (
+          (index[o.source] || index[o.target]) &&
+          (!o.hidden && !nodes(o.source).hidden && !nodes(o.target).hidden)
+        )
+          this.edgesOnScreen.push(o);
+      }
+
+      // If the "batchEdgesDrawing" settings is true, edges are batched:
+      if (this.settings(options, 'batchEdgesDrawing')) {
+        id = 'edges_' + this.conradId;
+        batchSize = embedSettings('canvasEdgesBatchSize');
+
+        edges = this.edgesOnScreen;
+        l = edges.length;
+
+        start = 0;
+        end = Math.min(edges.length, start + batchSize);
+
+        job = function() {
+          tempGCO = this.contexts.edges.globalCompositeOperation;
+          this.contexts.edges.globalCompositeOperation = 'destination-over';
+
+          renderers = sigma.canvas.edges;
+          for (i = start; i < end; i++) {
+            o = edges[i];
+            (renderers[
+              o.type || this.settings(options, 'defaultEdgeType')
+            ] || renderers.def)(
+              o,
+              graph.nodes(o.source),
+              graph.nodes(o.target),
+              this.contexts.edges,
+              embedSettings
+            );
+          }
+
+          // Draw edge labels:
+          if (drawEdgeLabels) {
+            renderers = sigma.canvas.edges.labels;
+            for (i = start; i < end; i++) {
+              o = edges[i];
+              if (!o.hidden)
+                (renderers[
+                  o.type || this.settings(options, 'defaultEdgeType')
+                ] || renderers.def)(
+                  o,
+                  graph.nodes(o.source),
+                  graph.nodes(o.target),
+                  this.contexts.labels,
+                  embedSettings
+                );
+            }
+          }
+
+          // Restore original globalCompositeOperation:
+          this.contexts.edges.globalCompositeOperation = tempGCO;
+
+          // Catch job's end:
+          if (end === edges.length) {
+            delete this.jobs[id];
+            return false;
+          }
+
+          start = end + 1;
+          end = Math.min(edges.length, start + batchSize);
+          return true;
+        };
+
+        this.jobs[id] = job;
+        conrad.addJob(id, job.bind(this));
+
+      // If not, they are drawn in one frame:
+      } else {
+        renderers = sigma.canvas.edges;
+        for (a = this.edgesOnScreen, i = 0, l = a.length; i < l; i++) {
+          o = a[i];
+          (renderers[
+            o.type || this.settings(options, 'defaultEdgeType')
+          ] || renderers.def)(
+            o,
+            graph.nodes(o.source),
+            graph.nodes(o.target),
+            this.contexts.edges,
+            embedSettings
+          );
+        }
+
+        // Draw edge labels:
+        // - No batching
+        if (drawEdgeLabels) {
+          renderers = sigma.canvas.edges.labels;
+          for (a = this.edgesOnScreen, i = 0, l = a.length; i < l; i++)
+            if (!a[i].hidden)
+              (renderers[
+                a[i].type || this.settings(options, 'defaultEdgeType')
+              ] || renderers.def)(
+                a[i],
+                graph.nodes(a[i].source),
+                graph.nodes(a[i].target),
+                this.contexts.labels,
+                embedSettings
+              );
+        }
+      }
+    }
+
+    // Draw nodes:
+    // - No batching
+    if (drawNodes) {
+      renderers = sigma.canvas.nodes;
+      for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++)
+        if (!a[i].hidden)
+          (renderers[
+            a[i].type || this.settings(options, 'defaultNodeType')
+          ] || renderers.def)(
+            a[i],
+            this.contexts.nodes,
+            embedSettings
+          );
+    }
+
+    // Draw labels:
+    // - No batching
+    if (drawLabels) {
+      renderers = sigma.canvas.labels;
+      for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++)
+        if (!a[i].hidden)
+          (renderers[
+            a[i].type || this.settings(options, 'defaultNodeType')
+          ] || renderers.def)(
+            a[i],
+            this.contexts.labels,
+            embedSettings
+          );
+    }
+
+    this.dispatchEvent('render');
+
+    return this;
+  };
+
+  /**
+   * This method creates a DOM element of the specified type, switches its
+   * position to "absolute", references it to the domElements attribute, and
+   * finally appends it to the container.
+   *
+   * @param  {string} tag The label tag.
+   * @param  {string} id  The id of the element (to store it in "domElements").
+   */
+  sigma.renderers.canvas.prototype.initDOM = function(tag, id) {
+    var dom = document.createElement(tag);
+
+    dom.style.position = 'absolute';
+    dom.setAttribute('class', 'sigma-' + id);
+
+    this.domElements[id] = dom;
+    this.container.appendChild(dom);
+
+    if (tag.toLowerCase() === 'canvas')
+      this.contexts[id] = dom.getContext('2d');
+  };
+
+  /**
+   * This method resizes each DOM elements in the container and stores the new
+   * dimensions. Then, it renders the graph.
+   *
+   * @param  {?number}                width  The new width of the container.
+   * @param  {?number}                height The new height of the container.
+   * @return {sigma.renderers.canvas}        Returns the instance itself.
+   */
+  sigma.renderers.canvas.prototype.resize = function(w, h) {
+    var k,
+        oldWidth = this.width,
+        oldHeight = this.height,
+        pixelRatio = sigma.utils.getPixelRatio();
+
+    if (w !== undefined && h !== undefined) {
+      this.width = w;
+      this.height = h;
+    } else {
+      this.width = this.container.offsetWidth;
+      this.height = this.container.offsetHeight;
+
+      w = this.width;
+      h = this.height;
+    }
+
+    if (oldWidth !== this.width || oldHeight !== this.height) {
+      for (k in this.domElements) {
+        this.domElements[k].style.width = w + 'px';
+        this.domElements[k].style.height = h + 'px';
+
+        if (this.domElements[k].tagName.toLowerCase() === 'canvas') {
+          this.domElements[k].setAttribute('width', (w * pixelRatio) + 'px');
+          this.domElements[k].setAttribute('height', (h * pixelRatio) + 'px');
+
+          if (pixelRatio !== 1)
+            this.contexts[k].scale(pixelRatio, pixelRatio);
+        }
+      }
+    }
+
+    return this;
+  };
+
+  /**
+   * This method clears each canvas.
+   *
+   * @return {sigma.renderers.canvas} Returns the instance itself.
+   */
+  sigma.renderers.canvas.prototype.clear = function() {
+    for (var k in this.contexts) {
+      this.contexts[k].clearRect(0, 0, this.width, this.height);
+    }
+
+    return this;
+  };
+
+  /**
+   * This method kills contexts and other attributes.
+   */
+  sigma.renderers.canvas.prototype.kill = function() {
+    var k,
+        captor;
+
+    // Kill captors:
+    while ((captor = this.captors.pop()))
+      captor.kill();
+    delete this.captors;
+
+    // Kill contexts:
+    for (k in this.domElements) {
+      this.domElements[k].parentNode.removeChild(this.domElements[k]);
+      delete this.domElements[k];
+      delete this.contexts[k];
+    }
+    delete this.domElements;
+    delete this.contexts;
+  };
+
+
+
+
+  /**
+   * The labels, nodes and edges renderers are stored in the three following
+   * objects. When an element is drawn, its type will be checked and if a
+   * renderer with the same name exists, it will be used. If not found, the
+   * default renderer will be used instead.
+   *
+   * They are stored in different files, in the "./canvas" folder.
+   */
+  sigma.utils.pkg('sigma.canvas.nodes');
+  sigma.utils.pkg('sigma.canvas.edges');
+  sigma.utils.pkg('sigma.canvas.labels');
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.renderers');
+
+  /**
+   * This function is the constructor of the canvas sigma's renderer.
+   *
+   * @param  {sigma.classes.graph}            graph    The graph to render.
+   * @param  {sigma.classes.camera}           camera   The camera.
+   * @param  {configurable}           settings The sigma instance settings
+   *                                           function.
+   * @param  {object}                 object   The options object.
+   * @return {sigma.renderers.canvas}          The renderer instance.
+   */
+  sigma.renderers.webgl = function(graph, camera, settings, options) {
+    if (typeof options !== 'object')
+      throw 'sigma.renderers.webgl: Wrong arguments.';
+
+    if (!(options.container instanceof HTMLElement))
+      throw 'Container not found.';
+
+    var k,
+        i,
+        l,
+        a,
+        fn,
+        _self = this;
+
+    sigma.classes.dispatcher.extend(this);
+
+    // Conrad related attributes:
+    this.jobs = {};
+
+    Object.defineProperty(this, 'conradId', {
+      value: sigma.utils.id()
+    });
+
+    // Initialize main attributes:
+    this.graph = graph;
+    this.camera = camera;
+    this.contexts = {};
+    this.domElements = {};
+    this.options = options;
+    this.container = this.options.container;
+    this.settings = (
+        typeof options.settings === 'object' &&
+        options.settings
+      ) ?
+        settings.embedObjects(options.settings) :
+        settings;
+
+    // Find the prefix:
+    this.options.prefix = this.camera.readPrefix;
+
+    // Initialize programs hash
+    Object.defineProperty(this, 'nodePrograms', {
+      value: {}
+    });
+    Object.defineProperty(this, 'edgePrograms', {
+      value: {}
+    });
+    Object.defineProperty(this, 'nodeFloatArrays', {
+      value: {}
+    });
+    Object.defineProperty(this, 'edgeFloatArrays', {
+      value: {}
+    });
+    Object.defineProperty(this, 'edgeIndicesArrays', {
+      value: {}
+    });
+
+    // Initialize the DOM elements:
+    if (this.settings(options, 'batchEdgesDrawing')) {
+      this.initDOM('canvas', 'edges', true);
+      this.initDOM('canvas', 'nodes', true);
+    } else {
+      this.initDOM('canvas', 'scene', true);
+      this.contexts.nodes = this.contexts.scene;
+      this.contexts.edges = this.contexts.scene;
+    }
+
+    this.initDOM('canvas', 'labels');
+    this.initDOM('canvas', 'mouse');
+    this.contexts.hover = this.contexts.mouse;
+
+    // Initialize captors:
+    this.captors = [];
+    a = this.options.captors || [sigma.captors.mouse, sigma.captors.touch];
+    for (i = 0, l = a.length; i < l; i++) {
+      fn = typeof a[i] === 'function' ? a[i] : sigma.captors[a[i]];
+      this.captors.push(
+        new fn(
+          this.domElements.mouse,
+          this.camera,
+          this.settings
+        )
+      );
+    }
+
+    // Deal with sigma events:
+    sigma.misc.bindEvents.call(this, this.camera.prefix);
+    sigma.misc.drawHovers.call(this, this.camera.prefix);
+
+    this.resize();
+  };
+
+
+
+
+  /**
+   * This method will generate the nodes and edges float arrays. This step is
+   * separated from the "render" method, because to keep WebGL efficient, since
+   * all the camera and middlewares are modelised as matrices and they do not
+   * require the float arrays to be regenerated.
+   *
+   * Basically, when the user moves the camera or applies some specific linear
+   * transformations, this process step will be skipped, and the "render"
+   * method will efficiently refresh the rendering.
+   *
+   * And when the user modifies the graph colors or positions (applying a new
+   * layout or filtering the colors, for instance), this "process" step will be
+   * required to regenerate the float arrays.
+   *
+   * @return {sigma.renderers.webgl} Returns the instance itself.
+   */
+  sigma.renderers.webgl.prototype.process = function() {
+    var a,
+        i,
+        l,
+        k,
+        type,
+        renderer,
+        graph = this.graph,
+        options = sigma.utils.extend(options, this.options),
+        defaultEdgeType = this.settings(options, 'defaultEdgeType'),
+        defaultNodeType = this.settings(options, 'defaultNodeType');
+
+    // Empty float arrays:
+    for (k in this.nodeFloatArrays)
+      delete this.nodeFloatArrays[k];
+
+    for (k in this.edgeFloatArrays)
+      delete this.edgeFloatArrays[k];
+
+    for (k in this.edgeIndicesArrays)
+      delete this.edgeIndicesArrays[k];
+
+    // Sort edges and nodes per types:
+    for (a = graph.edges(), i = 0, l = a.length; i < l; i++) {
+      type = a[i].type || defaultEdgeType;
+      k = (type && sigma.webgl.edges[type]) ? type : 'def';
+
+      if (!this.edgeFloatArrays[k])
+        this.edgeFloatArrays[k] = {
+          edges: []
+        };
+
+      this.edgeFloatArrays[k].edges.push(a[i]);
+    }
+
+    for (a = graph.nodes(), i = 0, l = a.length; i < l; i++) {
+      type = a[i].type || defaultNodeType;
+      k = (type && sigma.webgl.nodes[type]) ? type : 'def';
+
+      if (!this.nodeFloatArrays[k])
+        this.nodeFloatArrays[k] = {
+          nodes: []
+        };
+
+      this.nodeFloatArrays[k].nodes.push(a[i]);
+    }
+
+    // Push edges:
+    for (k in this.edgeFloatArrays) {
+      renderer = sigma.webgl.edges[k];
+      a = this.edgeFloatArrays[k].edges;
+
+      // Creating the necessary arrays
+      this.edgeFloatArrays[k].array = new Float32Array(
+        a.length * renderer.POINTS * renderer.ATTRIBUTES
+      );
+
+      for (i = 0, l = a.length; i < l; i++) {
+
+        // Just check that the edge and both its extremities are visible:
+        if (
+          !a[i].hidden &&
+          !graph.nodes(a[i].source).hidden &&
+          !graph.nodes(a[i].target).hidden
+        )
+          renderer.addEdge(
+            a[i],
+            graph.nodes(a[i].source),
+            graph.nodes(a[i].target),
+            this.edgeFloatArrays[k].array,
+            i * renderer.POINTS * renderer.ATTRIBUTES,
+            options.prefix,
+            this.settings
+          );
+      }
+
+      if (typeof renderer.computeIndices === 'function')
+        this.edgeIndicesArrays[k] = renderer.computeIndices(
+          this.edgeFloatArrays[k].array
+        );
+    }
+
+    // Push nodes:
+    for (k in this.nodeFloatArrays) {
+      renderer = sigma.webgl.nodes[k];
+      a = this.nodeFloatArrays[k].nodes;
+
+      // Creating the necessary arrays
+      this.nodeFloatArrays[k].array = new Float32Array(
+        a.length * renderer.POINTS * renderer.ATTRIBUTES
+      );
+
+      for (i = 0, l = a.length; i < l; i++) {
+        if (!this.nodeFloatArrays[k].array)
+          this.nodeFloatArrays[k].array = new Float32Array(
+            a.length * renderer.POINTS * renderer.ATTRIBUTES
+          );
+
+        // Just check that the edge and both its extremities are visible:
+        if (
+          !a[i].hidden
+        )
+          renderer.addNode(
+            a[i],
+            this.nodeFloatArrays[k].array,
+            i * renderer.POINTS * renderer.ATTRIBUTES,
+            options.prefix,
+            this.settings
+          );
+      }
+    }
+
+    return this;
+  };
+
+
+
+
+  /**
+   * This method renders the graph. It basically calls each program (and
+   * generate them if they do not exist yet) to render nodes and edges, batched
+   * per renderer.
+   *
+   * As in the canvas renderer, it is possible to display edges, nodes and / or
+   * labels in batches, to make the whole thing way more scalable.
+   *
+   * @param  {?object}               params Eventually an object of options.
+   * @return {sigma.renderers.webgl}        Returns the instance itself.
+   */
+  sigma.renderers.webgl.prototype.render = function(params) {
+    var a,
+        i,
+        l,
+        k,
+        o,
+        program,
+        renderer,
+        self = this,
+        graph = this.graph,
+        nodesGl = this.contexts.nodes,
+        edgesGl = this.contexts.edges,
+        matrix = this.camera.getMatrix(),
+        options = sigma.utils.extend(params, this.options),
+        drawLabels = this.settings(options, 'drawLabels'),
+        drawEdges = this.settings(options, 'drawEdges'),
+        drawNodes = this.settings(options, 'drawNodes');
+
+    // Call the resize function:
+    this.resize(false);
+
+    // Check the 'hideEdgesOnMove' setting:
+    if (this.settings(options, 'hideEdgesOnMove'))
+      if (this.camera.isAnimated || this.camera.isMoving)
+        drawEdges = false;
+
+    // Clear canvases:
+    this.clear();
+
+    // Translate matrix to [width/2, height/2]:
+    matrix = sigma.utils.matrices.multiply(
+      matrix,
+      sigma.utils.matrices.translation(this.width / 2, this.height / 2)
+    );
+
+    // Kill running jobs:
+    for (k in this.jobs)
+      if (conrad.hasJob(k))
+        conrad.killJob(k);
+
+    if (drawEdges) {
+      if (this.settings(options, 'batchEdgesDrawing'))
+        (function() {
+          var a,
+              k,
+              i,
+              id,
+              job,
+              arr,
+              end,
+              start,
+              indices,
+              renderer,
+              batchSize,
+              currentProgram;
+
+          id = 'edges_' + this.conradId;
+          batchSize = this.settings(options, 'webglEdgesBatchSize');
+          a = Object.keys(this.edgeFloatArrays);
+
+          if (!a.length)
+            return;
+          i = 0;
+          renderer = sigma.webgl.edges[a[i]];
+          arr = this.edgeFloatArrays[a[i]].array;
+          indices = this.edgeIndicesArrays[a[i]];
+          start = 0;
+          end = Math.min(
+            start + batchSize * renderer.POINTS,
+            arr.length / renderer.ATTRIBUTES
+          );
+
+          job = function() {
+            // Check program:
+            if (!this.edgePrograms[a[i]])
+              this.edgePrograms[a[i]] = renderer.initProgram(edgesGl);
+
+            if (start < end) {
+              edgesGl.useProgram(this.edgePrograms[a[i]]);
+              renderer.render(
+                edgesGl,
+                this.edgePrograms[a[i]],
+                arr,
+                {
+                  settings: this.settings,
+                  matrix: matrix,
+                  width: this.width,
+                  height: this.height,
+                  ratio: this.camera.ratio,
+                  scalingRatio: this.settings(
+                    options,
+                    'webglOversamplingRatio'
+                  ),
+                  start: start,
+                  count: end - start,
+                  indicesData: indices
+                }
+              );
+            }
+
+            // Catch job's end:
+            if (
+              end >= arr.length / renderer.ATTRIBUTES &&
+              i === a.length - 1
+            ) {
+              delete this.jobs[id];
+              return false;
+            }
+
+            if (end >= arr.length / renderer.ATTRIBUTES) {
+              i++;
+              arr = this.edgeFloatArrays[a[i]].array;
+              renderer = sigma.webgl.edges[a[i]];
+              start = 0;
+              end = Math.min(
+                start + batchSize * renderer.POINTS,
+                arr.length / renderer.ATTRIBUTES
+              );
+            } else {
+              start = end;
+              end = Math.min(
+                start + batchSize * renderer.POINTS,
+                arr.length / renderer.ATTRIBUTES
+              );
+            }
+
+            return true;
+          };
+
+          this.jobs[id] = job;
+          conrad.addJob(id, job.bind(this));
+        }).call(this);
+      else {
+        for (k in this.edgeFloatArrays) {
+          renderer = sigma.webgl.edges[k];
+
+          // Check program:
+          if (!this.edgePrograms[k])
+            this.edgePrograms[k] = renderer.initProgram(edgesGl);
+
+          // Render
+          if (this.edgeFloatArrays[k]) {
+            edgesGl.useProgram(this.edgePrograms[k]);
+            renderer.render(
+              edgesGl,
+              this.edgePrograms[k],
+              this.edgeFloatArrays[k].array,
+              {
+                settings: this.settings,
+                matrix: matrix,
+                width: this.width,
+                height: this.height,
+                ratio: this.camera.ratio,
+                scalingRatio: this.settings(options, 'webglOversamplingRatio'),
+                indicesData: this.edgeIndicesArrays[k]
+              }
+            );
+          }
+        }
+      }
+    }
+
+    if (drawNodes) {
+      // Enable blending:
+      nodesGl.blendFunc(nodesGl.SRC_ALPHA, nodesGl.ONE_MINUS_SRC_ALPHA);
+      nodesGl.enable(nodesGl.BLEND);
+
+      for (k in this.nodeFloatArrays) {
+        renderer = sigma.webgl.nodes[k];
+
+        // Check program:
+        if (!this.nodePrograms[k])
+          this.nodePrograms[k] = renderer.initProgram(nodesGl);
+
+        // Render
+        if (this.nodeFloatArrays[k]) {
+          nodesGl.useProgram(this.nodePrograms[k]);
+          renderer.render(
+            nodesGl,
+            this.nodePrograms[k],
+            this.nodeFloatArrays[k].array,
+            {
+              settings: this.settings,
+              matrix: matrix,
+              width: this.width,
+              height: this.height,
+              ratio: this.camera.ratio,
+              scalingRatio: this.settings(options, 'webglOversamplingRatio')
+            }
+          );
+        }
+      }
+    }
+
+    if (drawLabels) {
+      a = this.camera.quadtree.area(
+        this.camera.getRectangle(this.width, this.height)
+      );
+
+      // Apply camera view to these nodes:
+      this.camera.applyView(
+        undefined,
+        undefined,
+        {
+          nodes: a,
+          edges: [],
+          width: this.width,
+          height: this.height
+        }
+      );
+
+      o = function(key) {
+        return self.settings({
+          prefix: self.camera.prefix
+        }, key);
+      };
+
+      for (i = 0, l = a.length; i < l; i++)
+        if (!a[i].hidden)
+          (
+            sigma.canvas.labels[
+              a[i].type ||
+              this.settings(options, 'defaultNodeType')
+            ] || sigma.canvas.labels.def
+          )(a[i], this.contexts.labels, o);
+    }
+
+    this.dispatchEvent('render');
+
+    return this;
+  };
+
+
+
+
+  /**
+   * This method creates a DOM element of the specified type, switches its
+   * position to "absolute", references it to the domElements attribute, and
+   * finally appends it to the container.
+   *
+   * @param  {string}   tag   The label tag.
+   * @param  {string}   id    The id of the element (to store it in
+   *                          "domElements").
+   * @param  {?boolean} webgl Will init the WebGL context if true.
+   */
+  sigma.renderers.webgl.prototype.initDOM = function(tag, id, webgl) {
+    var gl,
+        dom = document.createElement(tag),
+        self = this;
+
+    dom.style.position = 'absolute';
+    dom.setAttribute('class', 'sigma-' + id);
+
+    this.domElements[id] = dom;
+    this.container.appendChild(dom);
+
+    if (tag.toLowerCase() === 'canvas') {
+      this.contexts[id] = dom.getContext(webgl ? 'experimental-webgl' : '2d', {
+        preserveDrawingBuffer: true
+      });
+
+      // Adding webgl context loss listeners
+      if (webgl) {
+        dom.addEventListener('webglcontextlost', function(e) {
+          e.preventDefault();
+        }, false);
+
+        dom.addEventListener('webglcontextrestored', function(e) {
+          self.render();
+        }, false);
+      }
+    }
+  };
+
+  /**
+   * This method resizes each DOM elements in the container and stores the new
+   * dimensions. Then, it renders the graph.
+   *
+   * @param  {?number}               width  The new width of the container.
+   * @param  {?number}               height The new height of the container.
+   * @return {sigma.renderers.webgl}        Returns the instance itself.
+   */
+  sigma.renderers.webgl.prototype.resize = function(w, h) {
+    var k,
+        oldWidth = this.width,
+        oldHeight = this.height,
+        pixelRatio = sigma.utils.getPixelRatio();
+
+    if (w !== undefined && h !== undefined) {
+      this.width = w;
+      this.height = h;
+    } else {
+      this.width = this.container.offsetWidth;
+      this.height = this.container.offsetHeight;
+
+      w = this.width;
+      h = this.height;
+    }
+
+    if (oldWidth !== this.width || oldHeight !== this.height) {
+      for (k in this.domElements) {
+        this.domElements[k].style.width = w + 'px';
+        this.domElements[k].style.height = h + 'px';
+
+        if (this.domElements[k].tagName.toLowerCase() === 'canvas') {
+          // If simple 2D canvas:
+          if (this.contexts[k] && this.contexts[k].scale) {
+            this.domElements[k].setAttribute('width', (w * pixelRatio) + 'px');
+            this.domElements[k].setAttribute('height', (h * pixelRatio) + 'px');
+
+            if (pixelRatio !== 1)
+              this.contexts[k].scale(pixelRatio, pixelRatio);
+          } else {
+            this.domElements[k].setAttribute(
+              'width',
+              (w * this.settings('webglOversamplingRatio')) + 'px'
+            );
+            this.domElements[k].setAttribute(
+              'height',
+              (h * this.settings('webglOversamplingRatio')) + 'px'
+            );
+          }
+        }
+      }
+    }
+
+    // Scale:
+    for (k in this.contexts)
+      if (this.contexts[k] && this.contexts[k].viewport)
+        this.contexts[k].viewport(
+          0,
+          0,
+          this.width * this.settings('webglOversamplingRatio'),
+          this.height * this.settings('webglOversamplingRatio')
+        );
+
+    return this;
+  };
+
+  /**
+   * This method clears each canvas.
+   *
+   * @return {sigma.renderers.webgl} Returns the instance itself.
+   */
+  sigma.renderers.webgl.prototype.clear = function() {
+    this.contexts.labels.clearRect(0, 0, this.width, this.height);
+    this.contexts.nodes.clear(this.contexts.nodes.COLOR_BUFFER_BIT);
+    this.contexts.edges.clear(this.contexts.edges.COLOR_BUFFER_BIT);
+
+    return this;
+  };
+
+  /**
+   * This method kills contexts and other attributes.
+   */
+  sigma.renderers.webgl.prototype.kill = function() {
+    var k,
+        captor;
+
+    // Kill captors:
+    while ((captor = this.captors.pop()))
+      captor.kill();
+    delete this.captors;
+
+    // Kill contexts:
+    for (k in this.domElements) {
+      this.domElements[k].parentNode.removeChild(this.domElements[k]);
+      delete this.domElements[k];
+      delete this.contexts[k];
+    }
+    delete this.domElements;
+    delete this.contexts;
+  };
+
+
+
+
+  /**
+   * The object "sigma.webgl.nodes" contains the different WebGL node
+   * renderers. The default one draw nodes as discs. Here are the attributes
+   * any node renderer must have:
+   *
+   * {number}   POINTS      The number of points required to draw a node.
+   * {number}   ATTRIBUTES  The number of attributes needed to draw one point.
+   * {function} addNode     A function that adds a node to the data stack that
+   *                        will be given to the buffer. Here is the arguments:
+   *                        > {object}       node
+   *                        > {number}       index   The node index in the
+   *                                                 nodes array.
+   *                        > {Float32Array} data    The stack.
+   *                        > {object}       options Some options.
+   * {function} render      The function that will effectively render the nodes
+   *                        into the buffer.
+   *                        > {WebGLRenderingContext} gl
+   *                        > {WebGLProgram}          program
+   *                        > {Float32Array} data    The stack to give to the
+   *                                                 buffer.
+   *                        > {object}       params  An object containing some
+   *                                                 options, like width,
+   *                                                 height, the camera ratio.
+   * {function} initProgram The function that will initiate the program, with
+   *                        the relevant shaders and parameters. It must return
+   *                        the newly created program.
+   *
+   * Check sigma.webgl.nodes.def or sigma.webgl.nodes.fast to see how it
+   * works more precisely.
+   */
+  sigma.utils.pkg('sigma.webgl.nodes');
+
+
+
+
+  /**
+   * The object "sigma.webgl.edges" contains the different WebGL edge
+   * renderers. The default one draw edges as direct lines. Here are the
+   * attributes any edge renderer must have:
+   *
+   * {number}   POINTS      The number of points required to draw an edge.
+   * {number}   ATTRIBUTES  The number of attributes needed to draw one point.
+   * {function} addEdge     A function that adds an edge to the data stack that
+   *                        will be given to the buffer. Here is the arguments:
+   *                        > {object}       edge
+   *                        > {object}       source
+   *                        > {object}       target
+   *                        > {Float32Array} data    The stack.
+   *                        > {object}       options Some options.
+   * {function} render      The function that will effectively render the edges
+   *                        into the buffer.
+   *                        > {WebGLRenderingContext} gl
+   *                        > {WebGLProgram}          program
+   *                        > {Float32Array} data    The stack to give to the
+   *                                                 buffer.
+   *                        > {object}       params  An object containing some
+   *                                                 options, like width,
+   *                                                 height, the camera ratio.
+   * {function} initProgram The function that will initiate the program, with
+   *                        the relevant shaders and parameters. It must return
+   *                        the newly created program.
+   *
+   * Check sigma.webgl.edges.def or sigma.webgl.edges.fast to see how it
+   * works more precisely.
+   */
+  sigma.utils.pkg('sigma.webgl.edges');
+
+
+
+
+  /**
+   * The object "sigma.canvas.labels" contains the different
+   * label renderers for the WebGL renderer. Since displaying texts in WebGL is
+   * definitely painful and since there a way less labels to display than nodes
+   * or edges, the default renderer simply renders them in a canvas.
+   *
+   * A labels renderer is a simple function, taking as arguments the related
+   * node, the renderer and a settings function.
+   */
+  sigma.utils.pkg('sigma.canvas.labels');
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  if (typeof conrad === 'undefined')
+    throw 'conrad is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.renderers');
+
+  /**
+   * This function is the constructor of the svg sigma's renderer.
+   *
+   * @param  {sigma.classes.graph}            graph    The graph to render.
+   * @param  {sigma.classes.camera}           camera   The camera.
+   * @param  {configurable}           settings The sigma instance settings
+   *                                           function.
+   * @param  {object}                 object   The options object.
+   * @return {sigma.renderers.svg}             The renderer instance.
+   */
+  sigma.renderers.svg = function(graph, camera, settings, options) {
+    if (typeof options !== 'object')
+      throw 'sigma.renderers.svg: Wrong arguments.';
+
+    if (!(options.container instanceof HTMLElement))
+      throw 'Container not found.';
+
+    var i,
+        l,
+        a,
+        fn,
+        self = this;
+
+    sigma.classes.dispatcher.extend(this);
+
+    // Initialize main attributes:
+    this.graph = graph;
+    this.camera = camera;
+    this.domElements = {
+      graph: null,
+      groups: {},
+      nodes: {},
+      edges: {},
+      labels: {},
+      hovers: {}
+    };
+    this.measurementCanvas = null;
+    this.options = options;
+    this.container = this.options.container;
+    this.settings = (
+        typeof options.settings === 'object' &&
+        options.settings
+      ) ?
+        settings.embedObjects(options.settings) :
+        settings;
+
+    // Is the renderer meant to be freestyle?
+    this.settings('freeStyle', !!this.options.freeStyle);
+
+    // SVG xmlns
+    this.settings('xmlns', 'http://www.w3.org/2000/svg');
+
+    // Indexes:
+    this.nodesOnScreen = [];
+    this.edgesOnScreen = [];
+
+    // Find the prefix:
+    this.options.prefix = 'renderer' + sigma.utils.id() + ':';
+
+    // Initialize the DOM elements
+    this.initDOM('svg');
+
+    // Initialize captors:
+    this.captors = [];
+    a = this.options.captors || [sigma.captors.mouse, sigma.captors.touch];
+    for (i = 0, l = a.length; i < l; i++) {
+      fn = typeof a[i] === 'function' ? a[i] : sigma.captors[a[i]];
+      this.captors.push(
+        new fn(
+          this.domElements.graph,
+          this.camera,
+          this.settings
+        )
+      );
+    }
+
+    // Bind resize:
+    window.addEventListener('resize', function() {
+      self.resize();
+    });
+
+    // Deal with sigma events:
+    // TODO: keep an option to override the DOM events?
+    sigma.misc.bindDOMEvents.call(this, this.domElements.graph);
+    this.bindHovers(this.options.prefix);
+
+    // Resize
+    this.resize(false);
+  };
+
+  /**
+   * This method renders the graph on the svg scene.
+   *
+   * @param  {?object}                options Eventually an object of options.
+   * @return {sigma.renderers.svg}            Returns the instance itself.
+   */
+  sigma.renderers.svg.prototype.render = function(options) {
+    options = options || {};
+
+    var a,
+        i,
+        k,
+        e,
+        l,
+        o,
+        source,
+        target,
+        start,
+        edges,
+        renderers,
+        subrenderers,
+        index = {},
+        graph = this.graph,
+        nodes = this.graph.nodes,
+        prefix = this.options.prefix || '',
+        drawEdges = this.settings(options, 'drawEdges'),
+        drawNodes = this.settings(options, 'drawNodes'),
+        drawLabels = this.settings(options, 'drawLabels'),
+        embedSettings = this.settings.embedObjects(options, {
+          prefix: this.options.prefix,
+          forceLabels: this.options.forceLabels
+        });
+
+    // Check the 'hideEdgesOnMove' setting:
+    if (this.settings(options, 'hideEdgesOnMove'))
+      if (this.camera.isAnimated || this.camera.isMoving)
+        drawEdges = false;
+
+    // Apply the camera's view:
+    this.camera.applyView(
+      undefined,
+      this.options.prefix,
+      {
+        width: this.width,
+        height: this.height
+      }
+    );
+
+    // Hiding everything
+    // TODO: find a more sensible way to perform this operation
+    this.hideDOMElements(this.domElements.nodes);
+    this.hideDOMElements(this.domElements.edges);
+    this.hideDOMElements(this.domElements.labels);
+
+    // Find which nodes are on screen
+    this.edgesOnScreen = [];
+    this.nodesOnScreen = this.camera.quadtree.area(
+      this.camera.getRectangle(this.width, this.height)
+    );
+
+    // Node index
+    for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++)
+      index[a[i].id] = a[i];
+
+    // Find which edges are on screen
+    for (a = graph.edges(), i = 0, l = a.length; i < l; i++) {
+      o = a[i];
+      if (
+        (index[o.source] || index[o.target]) &&
+        (!o.hidden && !nodes(o.source).hidden && !nodes(o.target).hidden)
+      )
+        this.edgesOnScreen.push(o);
+    }
+
+    // Display nodes
+    //---------------
+    renderers = sigma.svg.nodes;
+    subrenderers = sigma.svg.labels;
+
+    //-- First we create the nodes which are not already created
+    if (drawNodes)
+      for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++) {
+        if (!a[i].hidden && !this.domElements.nodes[a[i].id]) {
+
+          // Node
+          e = (renderers[a[i].type] || renderers.def).create(
+            a[i],
+            embedSettings
+          );
+
+          this.domElements.nodes[a[i].id] = e;
+          this.domElements.groups.nodes.appendChild(e);
+
+          // Label
+          e = (subrenderers[a[i].type] || subrenderers.def).create(
+            a[i],
+            embedSettings
+          );
+
+          this.domElements.labels[a[i].id] = e;
+          this.domElements.groups.labels.appendChild(e);
+        }
+      }
+
+    //-- Second we update the nodes
+    if (drawNodes)
+      for (a = this.nodesOnScreen, i = 0, l = a.length; i < l; i++) {
+
+        if (a[i].hidden)
+          continue;
+
+        // Node
+        (renderers[a[i].type] || renderers.def).update(
+          a[i],
+          this.domElements.nodes[a[i].id],
+          embedSettings
+        );
+
+        // Label
+        (subrenderers[a[i].type] || subrenderers.def).update(
+          a[i],
+          this.domElements.labels[a[i].id],
+          embedSettings
+        );
+      }
+
+    // Display edges
+    //---------------
+    renderers = sigma.svg.edges;
+
+    //-- First we create the edges which are not already created
+    if (drawEdges)
+      for (a = this.edgesOnScreen, i = 0, l = a.length; i < l; i++) {
+        if (!this.domElements.edges[a[i].id]) {
+          source = nodes(a[i].source);
+          target = nodes(a[i].target);
+
+          e = (renderers[a[i].type] || renderers.def).create(
+            a[i],
+            source,
+            target,
+            embedSettings
+          );
+
+          this.domElements.edges[a[i].id] = e;
+          this.domElements.groups.edges.appendChild(e);
+        }
+       }
+
+    //-- Second we update the edges
+    if (drawEdges)
+      for (a = this.edgesOnScreen, i = 0, l = a.length; i < l; i++) {
+        source = nodes(a[i].source);
+        target = nodes(a[i].target);
+
+        (renderers[a[i].type] || renderers.def).update(
+          a[i],
+          this.domElements.edges[a[i].id],
+          source,
+          target,
+          embedSettings
+        );
+       }
+
+    this.dispatchEvent('render');
+
+    return this;
+  };
+
+  /**
+   * This method creates a DOM element of the specified type, switches its
+   * position to "absolute", references it to the domElements attribute, and
+   * finally appends it to the container.
+   *
+   * @param  {string} tag The label tag.
+   * @param  {string} id  The id of the element (to store it in "domElements").
+   */
+  sigma.renderers.svg.prototype.initDOM = function(tag) {
+    var dom = document.createElementNS(this.settings('xmlns'), tag),
+        c = this.settings('classPrefix'),
+        g,
+        l,
+        i;
+
+    dom.style.position = 'absolute';
+    dom.setAttribute('class', c + '-svg');
+
+    // Setting SVG namespace
+    dom.setAttribute('xmlns', this.settings('xmlns'));
+    dom.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
+    dom.setAttribute('version', '1.1');
+
+    // Creating the measurement canvas
+    var canvas = document.createElement('canvas');
+    canvas.setAttribute('class', c + '-measurement-canvas');
+
+    // Appending elements
+    this.domElements.graph = this.container.appendChild(dom);
+
+    // Creating groups
+    var groups = ['edges', 'nodes', 'labels', 'hovers'];
+    for (i = 0, l = groups.length; i < l; i++) {
+      g = document.createElementNS(this.settings('xmlns'), 'g');
+
+      g.setAttributeNS(null, 'id', c + '-group-' + groups[i]);
+      g.setAttributeNS(null, 'class', c + '-group');
+
+      this.domElements.groups[groups[i]] =
+        this.domElements.graph.appendChild(g);
+    }
+
+    // Appending measurement canvas
+    this.container.appendChild(canvas);
+    this.measurementCanvas = canvas.getContext('2d');
+  };
+
+  /**
+   * This method hides a batch of SVG DOM elements.
+   *
+   * @param  {array}                  elements  An array of elements to hide.
+   * @param  {object}                 renderer  The renderer to use.
+   * @return {sigma.renderers.svg}              Returns the instance itself.
+   */
+  sigma.renderers.svg.prototype.hideDOMElements = function(elements) {
+    var o,
+        i;
+
+    for (i in elements) {
+      o = elements[i];
+      sigma.svg.utils.hide(o);
+    }
+
+    return this;
+  };
+
+  /**
+   * This method binds the hover events to the renderer.
+   *
+   * @param  {string} prefix The renderer prefix.
+   */
+  // TODO: add option about whether to display hovers or not
+  sigma.renderers.svg.prototype.bindHovers = function(prefix) {
+    var renderers = sigma.svg.hovers,
+        self = this,
+        hoveredNode;
+
+    function overNode(e) {
+      var node = e.data.node,
+          embedSettings = self.settings.embedObjects({
+            prefix: prefix
+          });
+
+      if (!embedSettings('enableHovering'))
+        return;
+
+      var hover = (renderers[node.type] || renderers.def).create(
+        node,
+        self.domElements.nodes[node.id],
+        self.measurementCanvas,
+        embedSettings
+      );
+
+      self.domElements.hovers[node.id] = hover;
+
+      // Inserting the hover in the dom
+      self.domElements.groups.hovers.appendChild(hover);
+      hoveredNode = node;
+    }
+
+    function outNode(e) {
+      var node = e.data.node,
+          embedSettings = self.settings.embedObjects({
+            prefix: prefix
+          });
+
+      if (!embedSettings('enableHovering'))
+        return;
+
+      // Deleting element
+      self.domElements.groups.hovers.removeChild(
+        self.domElements.hovers[node.id]
+      );
+      hoveredNode = null;
+      delete self.domElements.hovers[node.id];
+
+      // Reinstate
+      self.domElements.groups.nodes.appendChild(
+        self.domElements.nodes[node.id]
+      );
+    }
+
+    // OPTIMIZE: perform a real update rather than a deletion
+    function update() {
+      if (!hoveredNode)
+        return;
+
+      var embedSettings = self.settings.embedObjects({
+            prefix: prefix
+          });
+
+      // Deleting element before update
+      self.domElements.groups.hovers.removeChild(
+        self.domElements.hovers[hoveredNode.id]
+      );
+      delete self.domElements.hovers[hoveredNode.id];
+
+      var hover = (renderers[hoveredNode.type] || renderers.def).create(
+        hoveredNode,
+        self.domElements.nodes[hoveredNode.id],
+        self.measurementCanvas,
+        embedSettings
+      );
+
+      self.domElements.hovers[hoveredNode.id] = hover;
+
+      // Inserting the hover in the dom
+      self.domElements.groups.hovers.appendChild(hover);
+    }
+
+    // Binding events
+    this.bind('overNode', overNode);
+    this.bind('outNode', outNode);
+
+    // Update on render
+    this.bind('render', update);
+  };
+
+  /**
+   * This method resizes each DOM elements in the container and stores the new
+   * dimensions. Then, it renders the graph.
+   *
+   * @param  {?number}                width  The new width of the container.
+   * @param  {?number}                height The new height of the container.
+   * @return {sigma.renderers.svg}           Returns the instance itself.
+   */
+  sigma.renderers.svg.prototype.resize = function(w, h) {
+    var oldWidth = this.width,
+        oldHeight = this.height,
+        pixelRatio = 1;
+
+    if (w !== undefined && h !== undefined) {
+      this.width = w;
+      this.height = h;
+    } else {
+      this.width = this.container.offsetWidth;
+      this.height = this.container.offsetHeight;
+
+      w = this.width;
+      h = this.height;
+    }
+
+    if (oldWidth !== this.width || oldHeight !== this.height) {
+      this.domElements.graph.style.width = w + 'px';
+      this.domElements.graph.style.height = h + 'px';
+
+      if (this.domElements.graph.tagName.toLowerCase() === 'svg') {
+        this.domElements.graph.setAttribute('width', (w * pixelRatio));
+        this.domElements.graph.setAttribute('height', (h * pixelRatio));
+      }
+    }
+
+    return this;
+  };
+
+
+  /**
+   * The labels, nodes and edges renderers are stored in the three following
+   * objects. When an element is drawn, its type will be checked and if a
+   * renderer with the same name exists, it will be used. If not found, the
+   * default renderer will be used instead.
+   *
+   * They are stored in different files, in the "./svg" folder.
+   */
+  sigma.utils.pkg('sigma.svg.nodes');
+  sigma.utils.pkg('sigma.svg.edges');
+  sigma.utils.pkg('sigma.svg.labels');
+}).call(this);
+
+;(function(global) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.renderers');
+
+  // Check if WebGL is enabled:
+  var canvas,
+      webgl = !!global.WebGLRenderingContext;
+  if (webgl) {
+    canvas = document.createElement('canvas');
+    try {
+      webgl = !!(
+        canvas.getContext('webgl') ||
+        canvas.getContext('experimental-webgl')
+      );
+    } catch (e) {
+      webgl = false;
+    }
+  }
+
+  // Copy the good renderer:
+  sigma.renderers.def = webgl ?
+    sigma.renderers.webgl :
+    sigma.renderers.canvas;
+})(this);
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.webgl.nodes');
+
+  /**
+   * This node renderer will display nodes as discs, shaped in triangles with
+   * the gl.TRIANGLES display mode. So, to be more precise, to draw one node,
+   * it will store three times the center of node, with the color and the size,
+   * and an angle indicating which "corner" of the triangle to draw.
+   *
+   * The fragment shader does not deal with anti-aliasing, so make sure that
+   * you deal with it somewhere else in the code (by default, the WebGL
+   * renderer will oversample the rendering through the webglOversamplingRatio
+   * value).
+   */
+  sigma.webgl.nodes.def = {
+    POINTS: 3,
+    ATTRIBUTES: 5,
+    addNode: function(node, data, i, prefix, settings) {
+      var color = sigma.utils.floatColor(
+        node.color || settings('defaultNodeColor')
+      );
+
+      data[i++] = node[prefix + 'x'];
+      data[i++] = node[prefix + 'y'];
+      data[i++] = node[prefix + 'size'];
+      data[i++] = color;
+      data[i++] = 0;
+
+      data[i++] = node[prefix + 'x'];
+      data[i++] = node[prefix + 'y'];
+      data[i++] = node[prefix + 'size'];
+      data[i++] = color;
+      data[i++] = 2 * Math.PI / 3;
+
+      data[i++] = node[prefix + 'x'];
+      data[i++] = node[prefix + 'y'];
+      data[i++] = node[prefix + 'size'];
+      data[i++] = color;
+      data[i++] = 4 * Math.PI / 3;
+    },
+    render: function(gl, program, data, params) {
+      var buffer;
+
+      // Define attributes:
+      var positionLocation =
+            gl.getAttribLocation(program, 'a_position'),
+          sizeLocation =
+            gl.getAttribLocation(program, 'a_size'),
+          colorLocation =
+            gl.getAttribLocation(program, 'a_color'),
+          angleLocation =
+            gl.getAttribLocation(program, 'a_angle'),
+          resolutionLocation =
+            gl.getUniformLocation(program, 'u_resolution'),
+          matrixLocation =
+            gl.getUniformLocation(program, 'u_matrix'),
+          ratioLocation =
+            gl.getUniformLocation(program, 'u_ratio'),
+          scaleLocation =
+            gl.getUniformLocation(program, 'u_scale');
+
+      buffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+      gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
+
+      gl.uniform2f(resolutionLocation, params.width, params.height);
+      gl.uniform1f(
+        ratioLocation,
+        1 / Math.pow(params.ratio, params.settings('nodesPowRatio'))
+      );
+      gl.uniform1f(scaleLocation, params.scalingRatio);
+      gl.uniformMatrix3fv(matrixLocation, false, params.matrix);
+
+      gl.enableVertexAttribArray(positionLocation);
+      gl.enableVertexAttribArray(sizeLocation);
+      gl.enableVertexAttribArray(colorLocation);
+      gl.enableVertexAttribArray(angleLocation);
+
+      gl.vertexAttribPointer(
+        positionLocation,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        0
+      );
+      gl.vertexAttribPointer(
+        sizeLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        8
+      );
+      gl.vertexAttribPointer(
+        colorLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        12
+      );
+      gl.vertexAttribPointer(
+        angleLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        16
+      );
+
+      gl.drawArrays(
+        gl.TRIANGLES,
+        params.start || 0,
+        params.count || (data.length / this.ATTRIBUTES)
+      );
+    },
+    initProgram: function(gl) {
+      var vertexShader,
+          fragmentShader,
+          program;
+
+      vertexShader = sigma.utils.loadShader(
+        gl,
+        [
+          'attribute vec2 a_position;',
+          'attribute float a_size;',
+          'attribute float a_color;',
+          'attribute float a_angle;',
+
+          'uniform vec2 u_resolution;',
+          'uniform float u_ratio;',
+          'uniform float u_scale;',
+          'uniform mat3 u_matrix;',
+
+          'varying vec4 color;',
+          'varying vec2 center;',
+          'varying float radius;',
+
+          'void main() {',
+            // Multiply the point size twice:
+            'radius = a_size * u_ratio;',
+
+            // Scale from [[-1 1] [-1 1]] to the container:
+            'vec2 position = (u_matrix * vec3(a_position, 1)).xy;',
+            // 'center = (position / u_resolution * 2.0 - 1.0) * vec2(1, -1);',
+            'center = position * u_scale;',
+            'center = vec2(center.x, u_scale * u_resolution.y - center.y);',
+
+            'position = position +',
+              '2.0 * radius * vec2(cos(a_angle), sin(a_angle));',
+            'position = (position / u_resolution * 2.0 - 1.0) * vec2(1, -1);',
+
+            'radius = radius * u_scale;',
+
+            'gl_Position = vec4(position, 0, 1);',
+
+            // Extract the color:
+            'float c = a_color;',
+            'color.b = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.g = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;',
+            'color.a = 1.0;',
+          '}'
+        ].join('\n'),
+        gl.VERTEX_SHADER
+      );
+
+      fragmentShader = sigma.utils.loadShader(
+        gl,
+        [
+          'precision mediump float;',
+
+          'varying vec4 color;',
+          'varying vec2 center;',
+          'varying float radius;',
+
+          'void main(void) {',
+            'vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);',
+
+            'vec2 m = gl_FragCoord.xy - center;',
+            'float diff = radius - sqrt(m.x * m.x + m.y * m.y);',
+
+            // Here is how we draw a disc instead of a square:
+            'if (diff > 0.0)',
+              'gl_FragColor = color;',
+            'else',
+              'gl_FragColor = color0;',
+          '}'
+        ].join('\n'),
+        gl.FRAGMENT_SHADER
+      );
+
+      program = sigma.utils.loadProgram(gl, [vertexShader, fragmentShader]);
+
+      return program;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.webgl.nodes');
+
+  /**
+   * This node renderer will display nodes in the fastest way: Nodes are basic
+   * squares, drawn through the gl.POINTS drawing method. The size of the nodes
+   * are represented with the "gl_PointSize" value in the vertex shader.
+   *
+   * It is the fastest node renderer here since the buffer just takes one line
+   * to draw each node (with attributes "x", "y", "size" and "color").
+   *
+   * Nevertheless, this method has some problems, especially due to some issues
+   * with the gl.POINTS:
+   *  - First, if the center of a node is outside the scene, the point will not
+   *    be drawn, even if it should be partly on screen.
+   *  - I tried applying a fragment shader similar to the one in the default
+   *    node renderer to display them as discs, but it did not work fine on
+   *    some computers settings, filling the discs with weird gradients not
+   *    depending on the actual color.
+   */
+  sigma.webgl.nodes.fast = {
+    POINTS: 1,
+    ATTRIBUTES: 4,
+    addNode: function(node, data, i, prefix, settings) {
+      data[i++] = node[prefix + 'x'];
+      data[i++] = node[prefix + 'y'];
+      data[i++] = node[prefix + 'size'];
+      data[i++] = sigma.utils.floatColor(
+        node.color || settings('defaultNodeColor')
+      );
+    },
+    render: function(gl, program, data, params) {
+      var buffer;
+
+      // Define attributes:
+      var positionLocation =
+            gl.getAttribLocation(program, 'a_position'),
+          sizeLocation =
+            gl.getAttribLocation(program, 'a_size'),
+          colorLocation =
+            gl.getAttribLocation(program, 'a_color'),
+          resolutionLocation =
+            gl.getUniformLocation(program, 'u_resolution'),
+          matrixLocation =
+            gl.getUniformLocation(program, 'u_matrix'),
+          ratioLocation =
+            gl.getUniformLocation(program, 'u_ratio'),
+          scaleLocation =
+            gl.getUniformLocation(program, 'u_scale');
+
+      buffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+      gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
+
+      gl.uniform2f(resolutionLocation, params.width, params.height);
+      gl.uniform1f(
+        ratioLocation,
+        1 / Math.pow(params.ratio, params.settings('nodesPowRatio'))
+      );
+      gl.uniform1f(scaleLocation, params.scalingRatio);
+      gl.uniformMatrix3fv(matrixLocation, false, params.matrix);
+
+      gl.enableVertexAttribArray(positionLocation);
+      gl.enableVertexAttribArray(sizeLocation);
+      gl.enableVertexAttribArray(colorLocation);
+
+      gl.vertexAttribPointer(
+        positionLocation,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        0
+      );
+      gl.vertexAttribPointer(
+        sizeLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        8
+      );
+      gl.vertexAttribPointer(
+        colorLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        12
+      );
+
+      gl.drawArrays(
+        gl.POINTS,
+        params.start || 0,
+        params.count || (data.length / this.ATTRIBUTES)
+      );
+    },
+    initProgram: function(gl) {
+      var vertexShader,
+          fragmentShader,
+          program;
+
+      vertexShader = sigma.utils.loadShader(
+        gl,
+        [
+          'attribute vec2 a_position;',
+          'attribute float a_size;',
+          'attribute float a_color;',
+
+          'uniform vec2 u_resolution;',
+          'uniform float u_ratio;',
+          'uniform float u_scale;',
+          'uniform mat3 u_matrix;',
+
+          'varying vec4 color;',
+
+          'void main() {',
+            // Scale from [[-1 1] [-1 1]] to the container:
+            'gl_Position = vec4(',
+              '((u_matrix * vec3(a_position, 1)).xy /',
+                'u_resolution * 2.0 - 1.0) * vec2(1, -1),',
+              '0,',
+              '1',
+            ');',
+
+            // Multiply the point size twice:
+            //  - x SCALING_RATIO to correct the canvas scaling
+            //  - x 2 to correct the formulae
+            'gl_PointSize = a_size * u_ratio * u_scale * 2.0;',
+
+            // Extract the color:
+            'float c = a_color;',
+            'color.b = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.g = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;',
+            'color.a = 1.0;',
+          '}'
+        ].join('\n'),
+        gl.VERTEX_SHADER
+      );
+
+      fragmentShader = sigma.utils.loadShader(
+        gl,
+        [
+          'precision mediump float;',
+
+          'varying vec4 color;',
+
+          'void main(void) {',
+            'float border = 0.01;',
+            'float radius = 0.5;',
+
+            'vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);',
+            'vec2 m = gl_PointCoord - vec2(0.5, 0.5);',
+            'float dist = radius - sqrt(m.x * m.x + m.y * m.y);',
+
+            'float t = 0.0;',
+            'if (dist > border)',
+              't = 1.0;',
+            'else if (dist > 0.0)',
+              't = dist / border;',
+
+            'gl_FragColor = mix(color0, color, t);',
+          '}'
+        ].join('\n'),
+        gl.FRAGMENT_SHADER
+      );
+
+      program = sigma.utils.loadProgram(gl, [vertexShader, fragmentShader]);
+
+      return program;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.webgl.edges');
+
+  /**
+   * This edge renderer will display edges as lines going from the source node
+   * to the target node. To deal with edge thicknesses, the lines are made of
+   * two triangles forming rectangles, with the gl.TRIANGLES drawing mode.
+   *
+   * It is expensive, since drawing a single edge requires 6 points, each
+   * having 7 attributes (source position, target position, thickness, color
+   * and a flag indicating which vertice of the rectangle it is).
+   */
+  sigma.webgl.edges.def = {
+    POINTS: 6,
+    ATTRIBUTES: 7,
+    addEdge: function(edge, source, target, data, i, prefix, settings) {
+      var w = (edge[prefix + 'size'] || 1) / 2,
+          x1 = source[prefix + 'x'],
+          y1 = source[prefix + 'y'],
+          x2 = target[prefix + 'x'],
+          y2 = target[prefix + 'y'],
+          color = edge.color;
+
+      if (!color)
+        switch (settings('edgeColor')) {
+          case 'source':
+            color = source.color || settings('defaultNodeColor');
+            break;
+          case 'target':
+            color = target.color || settings('defaultNodeColor');
+            break;
+          default:
+            color = settings('defaultEdgeColor');
+            break;
+        }
+
+      // Normalize color:
+      color = sigma.utils.floatColor(color);
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = 1.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = 1.0;
+      data[i++] = color;
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = 0.0;
+      data[i++] = color;
+    },
+    render: function(gl, program, data, params) {
+      var buffer;
+
+      // Define attributes:
+      var colorLocation =
+            gl.getAttribLocation(program, 'a_color'),
+          positionLocation1 =
+            gl.getAttribLocation(program, 'a_position1'),
+          positionLocation2 =
+            gl.getAttribLocation(program, 'a_position2'),
+          thicknessLocation =
+            gl.getAttribLocation(program, 'a_thickness'),
+          minusLocation =
+            gl.getAttribLocation(program, 'a_minus'),
+          resolutionLocation =
+            gl.getUniformLocation(program, 'u_resolution'),
+          matrixLocation =
+            gl.getUniformLocation(program, 'u_matrix'),
+          matrixHalfPiLocation =
+            gl.getUniformLocation(program, 'u_matrixHalfPi'),
+          matrixHalfPiMinusLocation =
+            gl.getUniformLocation(program, 'u_matrixHalfPiMinus'),
+          ratioLocation =
+            gl.getUniformLocation(program, 'u_ratio'),
+          scaleLocation =
+            gl.getUniformLocation(program, 'u_scale');
+
+      buffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+      gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
+
+      gl.uniform2f(resolutionLocation, params.width, params.height);
+      gl.uniform1f(
+        ratioLocation,
+        params.ratio / Math.pow(params.ratio, params.settings('edgesPowRatio'))
+      );
+      gl.uniform1f(scaleLocation, params.scalingRatio);
+      gl.uniformMatrix3fv(matrixLocation, false, params.matrix);
+      gl.uniformMatrix2fv(
+        matrixHalfPiLocation,
+        false,
+        sigma.utils.matrices.rotation(Math.PI / 2, true)
+      );
+      gl.uniformMatrix2fv(
+        matrixHalfPiMinusLocation,
+        false,
+        sigma.utils.matrices.rotation(-Math.PI / 2, true)
+      );
+
+      gl.enableVertexAttribArray(colorLocation);
+      gl.enableVertexAttribArray(positionLocation1);
+      gl.enableVertexAttribArray(positionLocation2);
+      gl.enableVertexAttribArray(thicknessLocation);
+      gl.enableVertexAttribArray(minusLocation);
+
+      gl.vertexAttribPointer(positionLocation1,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        0
+      );
+      gl.vertexAttribPointer(positionLocation2,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        8
+      );
+      gl.vertexAttribPointer(thicknessLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        16
+      );
+      gl.vertexAttribPointer(minusLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        20
+      );
+      gl.vertexAttribPointer(colorLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        24
+      );
+
+      gl.drawArrays(
+        gl.TRIANGLES,
+        params.start || 0,
+        params.count || (data.length / this.ATTRIBUTES)
+      );
+    },
+    initProgram: function(gl) {
+      var vertexShader,
+          fragmentShader,
+          program;
+
+      vertexShader = sigma.utils.loadShader(
+        gl,
+        [
+          'attribute vec2 a_position1;',
+          'attribute vec2 a_position2;',
+          'attribute float a_thickness;',
+          'attribute float a_minus;',
+          'attribute float a_color;',
+
+          'uniform vec2 u_resolution;',
+          'uniform float u_ratio;',
+          'uniform float u_scale;',
+          'uniform mat3 u_matrix;',
+          'uniform mat2 u_matrixHalfPi;',
+          'uniform mat2 u_matrixHalfPiMinus;',
+
+          'varying vec4 color;',
+
+          'void main() {',
+            // Find the good point:
+            'vec2 position = a_thickness * u_ratio *',
+              'normalize(a_position2 - a_position1);',
+
+            'mat2 matrix = a_minus * u_matrixHalfPiMinus +',
+              '(1.0 - a_minus) * u_matrixHalfPi;',
+
+            'position = matrix * position + a_position1;',
+
+            // Scale from [[-1 1] [-1 1]] to the container:
+            'gl_Position = vec4(',
+              '((u_matrix * vec3(position, 1)).xy /',
+                'u_resolution * 2.0 - 1.0) * vec2(1, -1),',
+              '0,',
+              '1',
+            ');',
+
+            // Extract the color:
+            'float c = a_color;',
+            'color.b = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.g = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;',
+            'color.a = 1.0;',
+          '}'
+        ].join('\n'),
+        gl.VERTEX_SHADER
+      );
+
+      fragmentShader = sigma.utils.loadShader(
+        gl,
+        [
+          'precision mediump float;',
+
+          'varying vec4 color;',
+
+          'void main(void) {',
+            'gl_FragColor = color;',
+          '}'
+        ].join('\n'),
+        gl.FRAGMENT_SHADER
+      );
+
+      program = sigma.utils.loadProgram(gl, [vertexShader, fragmentShader]);
+
+      return program;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.webgl.edges');
+
+  /**
+   * This edge renderer will display edges as lines with the gl.LINES display
+   * mode. Since this mode does not support well thickness, edges are all drawn
+   * with the same thickness (3px), independantly of the edge attributes or the
+   * zooming ratio.
+   */
+  sigma.webgl.edges.fast = {
+    POINTS: 2,
+    ATTRIBUTES: 3,
+    addEdge: function(edge, source, target, data, i, prefix, settings) {
+      var w = (edge[prefix + 'size'] || 1) / 2,
+          x1 = source[prefix + 'x'],
+          y1 = source[prefix + 'y'],
+          x2 = target[prefix + 'x'],
+          y2 = target[prefix + 'y'],
+          color = edge.color;
+
+      if (!color)
+        switch (settings('edgeColor')) {
+          case 'source':
+            color = source.color || settings('defaultNodeColor');
+            break;
+          case 'target':
+            color = target.color || settings('defaultNodeColor');
+            break;
+          default:
+            color = settings('defaultEdgeColor');
+            break;
+        }
+
+      // Normalize color:
+      color = sigma.utils.floatColor(color);
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = color;
+    },
+    render: function(gl, program, data, params) {
+      var buffer;
+
+      // Define attributes:
+      var colorLocation =
+            gl.getAttribLocation(program, 'a_color'),
+          positionLocation =
+            gl.getAttribLocation(program, 'a_position'),
+          resolutionLocation =
+            gl.getUniformLocation(program, 'u_resolution'),
+          matrixLocation =
+            gl.getUniformLocation(program, 'u_matrix');
+
+      buffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+      gl.bufferData(gl.ARRAY_BUFFER, data, gl.DYNAMIC_DRAW);
+
+      gl.uniform2f(resolutionLocation, params.width, params.height);
+      gl.uniformMatrix3fv(matrixLocation, false, params.matrix);
+
+      gl.enableVertexAttribArray(positionLocation);
+      gl.enableVertexAttribArray(colorLocation);
+
+      gl.vertexAttribPointer(positionLocation,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        0
+      );
+      gl.vertexAttribPointer(colorLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        8
+      );
+
+      gl.lineWidth(3);
+      gl.drawArrays(
+        gl.LINES,
+        params.start || 0,
+        params.count || (data.length / this.ATTRIBUTES)
+      );
+    },
+    initProgram: function(gl) {
+      var vertexShader,
+          fragmentShader,
+          program;
+
+      vertexShader = sigma.utils.loadShader(
+        gl,
+        [
+          'attribute vec2 a_position;',
+          'attribute float a_color;',
+
+          'uniform vec2 u_resolution;',
+          'uniform mat3 u_matrix;',
+
+          'varying vec4 color;',
+
+          'void main() {',
+            // Scale from [[-1 1] [-1 1]] to the container:
+            'gl_Position = vec4(',
+              '((u_matrix * vec3(a_position, 1)).xy /',
+                'u_resolution * 2.0 - 1.0) * vec2(1, -1),',
+              '0,',
+              '1',
+            ');',
+
+            // Extract the color:
+            'float c = a_color;',
+            'color.b = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.g = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;',
+            'color.a = 1.0;',
+          '}'
+        ].join('\n'),
+        gl.VERTEX_SHADER
+      );
+
+      fragmentShader = sigma.utils.loadShader(
+        gl,
+        [
+          'precision mediump float;',
+
+          'varying vec4 color;',
+
+          'void main(void) {',
+            'gl_FragColor = color;',
+          '}'
+        ].join('\n'),
+        gl.FRAGMENT_SHADER
+      );
+
+      program = sigma.utils.loadProgram(gl, [vertexShader, fragmentShader]);
+
+      return program;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.webgl.edges');
+
+  /**
+   * This edge renderer will display edges as arrows going from the source node
+   * to the target node. To deal with edge thicknesses, the lines are made of
+   * three triangles: two forming rectangles, with the gl.TRIANGLES drawing
+   * mode.
+   *
+   * It is expensive, since drawing a single edge requires 9 points, each
+   * having a lot of attributes.
+   */
+  sigma.webgl.edges.arrow = {
+    POINTS: 9,
+    ATTRIBUTES: 11,
+    addEdge: function(edge, source, target, data, i, prefix, settings) {
+      var w = (edge[prefix + 'size'] || 1) / 2,
+          x1 = source[prefix + 'x'],
+          y1 = source[prefix + 'y'],
+          x2 = target[prefix + 'x'],
+          y2 = target[prefix + 'y'],
+          targetSize = target[prefix + 'size'],
+          color = edge.color;
+
+      if (!color)
+        switch (settings('edgeColor')) {
+          case 'source':
+            color = source.color || settings('defaultNodeColor');
+            break;
+          case 'target':
+            color = target.color || settings('defaultNodeColor');
+            break;
+          default:
+            color = settings('defaultEdgeColor');
+            break;
+        }
+
+      // Normalize color:
+      color = sigma.utils.floatColor(color);
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 0.0;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      // Arrow head:
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 1.0;
+      data[i++] = -1.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = color;
+
+      data[i++] = x2;
+      data[i++] = y2;
+      data[i++] = x1;
+      data[i++] = y1;
+      data[i++] = w;
+      data[i++] = targetSize;
+      data[i++] = 1.0;
+      data[i++] = 0.0;
+      data[i++] = 1.0;
+      data[i++] = 1.0;
+      data[i++] = color;
+    },
+    render: function(gl, program, data, params) {
+      var buffer;
+
+      // Define attributes:
+      var positionLocation1 =
+            gl.getAttribLocation(program, 'a_pos1'),
+          positionLocation2 =
+            gl.getAttribLocation(program, 'a_pos2'),
+          thicknessLocation =
+            gl.getAttribLocation(program, 'a_thickness'),
+          targetSizeLocation =
+            gl.getAttribLocation(program, 'a_tSize'),
+          delayLocation =
+            gl.getAttribLocation(program, 'a_delay'),
+          minusLocation =
+            gl.getAttribLocation(program, 'a_minus'),
+          headLocation =
+            gl.getAttribLocation(program, 'a_head'),
+          headPositionLocation =
+            gl.getAttribLocation(program, 'a_headPosition'),
+          colorLocation =
+            gl.getAttribLocation(program, 'a_color'),
+          resolutionLocation =
+            gl.getUniformLocation(program, 'u_resolution'),
+          matrixLocation =
+            gl.getUniformLocation(program, 'u_matrix'),
+          matrixHalfPiLocation =
+            gl.getUniformLocation(program, 'u_matrixHalfPi'),
+          matrixHalfPiMinusLocation =
+            gl.getUniformLocation(program, 'u_matrixHalfPiMinus'),
+          ratioLocation =
+            gl.getUniformLocation(program, 'u_ratio'),
+          nodeRatioLocation =
+            gl.getUniformLocation(program, 'u_nodeRatio'),
+          arrowHeadLocation =
+            gl.getUniformLocation(program, 'u_arrowHead'),
+          scaleLocation =
+            gl.getUniformLocation(program, 'u_scale');
+
+      buffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+      gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
+
+      gl.uniform2f(resolutionLocation, params.width, params.height);
+      gl.uniform1f(
+        ratioLocation,
+        params.ratio / Math.pow(params.ratio, params.settings('edgesPowRatio'))
+      );
+      gl.uniform1f(
+        nodeRatioLocation,
+        Math.pow(params.ratio, params.settings('nodesPowRatio')) /
+        params.ratio
+      );
+      gl.uniform1f(arrowHeadLocation, 5.0);
+      gl.uniform1f(scaleLocation, params.scalingRatio);
+      gl.uniformMatrix3fv(matrixLocation, false, params.matrix);
+      gl.uniformMatrix2fv(
+        matrixHalfPiLocation,
+        false,
+        sigma.utils.matrices.rotation(Math.PI / 2, true)
+      );
+      gl.uniformMatrix2fv(
+        matrixHalfPiMinusLocation,
+        false,
+        sigma.utils.matrices.rotation(-Math.PI / 2, true)
+      );
+
+      gl.enableVertexAttribArray(positionLocation1);
+      gl.enableVertexAttribArray(positionLocation2);
+      gl.enableVertexAttribArray(thicknessLocation);
+      gl.enableVertexAttribArray(targetSizeLocation);
+      gl.enableVertexAttribArray(delayLocation);
+      gl.enableVertexAttribArray(minusLocation);
+      gl.enableVertexAttribArray(headLocation);
+      gl.enableVertexAttribArray(headPositionLocation);
+      gl.enableVertexAttribArray(colorLocation);
+
+      gl.vertexAttribPointer(positionLocation1,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        0
+      );
+      gl.vertexAttribPointer(positionLocation2,
+        2,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        8
+      );
+      gl.vertexAttribPointer(thicknessLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        16
+      );
+      gl.vertexAttribPointer(targetSizeLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        20
+      );
+      gl.vertexAttribPointer(delayLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        24
+      );
+      gl.vertexAttribPointer(minusLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        28
+      );
+      gl.vertexAttribPointer(headLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        32
+      );
+      gl.vertexAttribPointer(headPositionLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        36
+      );
+      gl.vertexAttribPointer(colorLocation,
+        1,
+        gl.FLOAT,
+        false,
+        this.ATTRIBUTES * Float32Array.BYTES_PER_ELEMENT,
+        40
+      );
+
+      gl.drawArrays(
+        gl.TRIANGLES,
+        params.start || 0,
+        params.count || (data.length / this.ATTRIBUTES)
+      );
+    },
+    initProgram: function(gl) {
+      var vertexShader,
+          fragmentShader,
+          program;
+
+      vertexShader = sigma.utils.loadShader(
+        gl,
+        [
+          'attribute vec2 a_pos1;',
+          'attribute vec2 a_pos2;',
+          'attribute float a_thickness;',
+          'attribute float a_tSize;',
+          'attribute float a_delay;',
+          'attribute float a_minus;',
+          'attribute float a_head;',
+          'attribute float a_headPosition;',
+          'attribute float a_color;',
+
+          'uniform vec2 u_resolution;',
+          'uniform float u_ratio;',
+          'uniform float u_nodeRatio;',
+          'uniform float u_arrowHead;',
+          'uniform float u_scale;',
+          'uniform mat3 u_matrix;',
+          'uniform mat2 u_matrixHalfPi;',
+          'uniform mat2 u_matrixHalfPiMinus;',
+
+          'varying vec4 color;',
+
+          'void main() {',
+            // Find the good point:
+            'vec2 pos = normalize(a_pos2 - a_pos1);',
+
+            'mat2 matrix = (1.0 - a_head) *',
+              '(',
+                'a_minus * u_matrixHalfPiMinus +',
+                '(1.0 - a_minus) * u_matrixHalfPi',
+              ') + a_head * (',
+                'a_headPosition * u_matrixHalfPiMinus * 0.6 +',
+                '(a_headPosition * a_headPosition - 1.0) * mat2(1.0)',
+              ');',
+
+            'pos = a_pos1 + (',
+              // Deal with body:
+              '(1.0 - a_head) * a_thickness * u_ratio * matrix * pos +',
+              // Deal with head:
+              'a_head * u_arrowHead * a_thickness * u_ratio * matrix * pos +',
+              // Deal with delay:
+              'a_delay * pos * (',
+                'a_tSize / u_nodeRatio +',
+                'u_arrowHead * a_thickness * u_ratio',
+              ')',
+            ');',
+
+            // Scale from [[-1 1] [-1 1]] to the container:
+            'gl_Position = vec4(',
+              '((u_matrix * vec3(pos, 1)).xy /',
+                'u_resolution * 2.0 - 1.0) * vec2(1, -1),',
+              '0,',
+              '1',
+            ');',
+
+            // Extract the color:
+            'float c = a_color;',
+            'color.b = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.g = mod(c, 256.0); c = floor(c / 256.0);',
+            'color.r = mod(c, 256.0); c = floor(c / 256.0); color /= 255.0;',
+            'color.a = 1.0;',
+          '}'
+        ].join('\n'),
+        gl.VERTEX_SHADER
+      );
+
+      fragmentShader = sigma.utils.loadShader(
+        gl,
+        [
+          'precision mediump float;',
+
+          'varying vec4 color;',
+
+          'void main(void) {',
+            'gl_FragColor = color;',
+          '}'
+        ].join('\n'),
+        gl.FRAGMENT_SHADER
+      );
+
+      program = sigma.utils.loadProgram(gl, [vertexShader, fragmentShader]);
+
+      return program;
+    }
+  };
+})();
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.canvas.labels');
+
+  /**
+   * This label renderer will just display the label on the right of the node.
+   *
+   * @param  {object}                   node     The node object.
+   * @param  {CanvasRenderingContext2D} context  The canvas context.
+   * @param  {configurable}             settings The settings function.
+   */
+  sigma.canvas.labels.def = function(node, context, settings) {
+    var fontSize,
+        prefix = settings('prefix') || '',
+        size = node[prefix + 'size'];
+
+    if (size < settings('labelThreshold'))
+      return;
+
+    if (!node.label || typeof node.label !== 'string')
+      return;
+
+    fontSize = (settings('labelSize') === 'fixed') ?
+      settings('defaultLabelSize') :
+      settings('labelSizeRatio') * size;
+
+    context.font = (settings('fontStyle') ? settings('fontStyle') + ' ' : '') +
+      fontSize + 'px ' + settings('font');
+    context.fillStyle = (settings('labelColor') === 'node') ?
+      (node.color || settings('defaultNodeColor')) :
+      settings('defaultLabelColor');
+
+    context.fillText(
+      node.label,
+      Math.round(node[prefix + 'x'] + size + 3),
+      Math.round(node[prefix + 'y'] + fontSize / 3)
+    );
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.canvas.hovers');
+
+  /**
+   * This hover renderer will basically display the label with a background.
+   *
+   * @param  {object}                   node     The node object.
+   * @param  {CanvasRenderingContext2D} context  The canvas context.
+   * @param  {configurable}             settings The settings function.
+   */
+  sigma.canvas.hovers.def = function(node, context, settings) {
+    var x,
+        y,
+        w,
+        h,
+        e,
+        fontStyle = settings('hoverFontStyle') || settings('fontStyle'),
+        prefix = settings('prefix') || '',
+        size = node[prefix + 'size'],
+        fontSize = (settings('labelSize') === 'fixed') ?
+          settings('defaultLabelSize') :
+          settings('labelSizeRatio') * size;
+
+    // Label background:
+    context.font = (fontStyle ? fontStyle + ' ' : '') +
+      fontSize + 'px ' + (settings('hoverFont') || settings('font'));
+
+    context.beginPath();
+    context.fillStyle = settings('labelHoverBGColor') === 'node' ?
+      (node.color || settings('defaultNodeColor')) :
+      settings('defaultHoverLabelBGColor');
+
+    if (node.label && settings('labelHoverShadow')) {
+      context.shadowOffsetX = 0;
+      context.shadowOffsetY = 0;
+      context.shadowBlur = 8;
+      context.shadowColor = settings('labelHoverShadowColor');
+    }
+
+    if (node.label && typeof node.label === 'string') {
+      x = Math.round(node[prefix + 'x'] - fontSize / 2 - 2);
+      y = Math.round(node[prefix + 'y'] - fontSize / 2 - 2);
+      w = Math.round(
+        context.measureText(node.label).width + fontSize / 2 + size + 7
+      );
+      h = Math.round(fontSize + 4);
+      e = Math.round(fontSize / 2 + 2);
+
+      context.moveTo(x, y + e);
+      context.arcTo(x, y, x + e, y, e);
+      context.lineTo(x + w, y);
+      context.lineTo(x + w, y + h);
+      context.lineTo(x + e, y + h);
+      context.arcTo(x, y + h, x, y + h - e, e);
+      context.lineTo(x, y + e);
+
+      context.closePath();
+      context.fill();
+
+      context.shadowOffsetX = 0;
+      context.shadowOffsetY = 0;
+      context.shadowBlur = 0;
+    }
+
+    // Node border:
+    if (settings('borderSize') > 0) {
+      context.beginPath();
+      context.fillStyle = settings('nodeBorderColor') === 'node' ?
+        (node.color || settings('defaultNodeColor')) :
+        settings('defaultNodeBorderColor');
+      context.arc(
+        node[prefix + 'x'],
+        node[prefix + 'y'],
+        size + settings('borderSize'),
+        0,
+        Math.PI * 2,
+        true
+      );
+      context.closePath();
+      context.fill();
+    }
+
+    // Node:
+    var nodeRenderer = sigma.canvas.nodes[node.type] || sigma.canvas.nodes.def;
+    nodeRenderer(node, context, settings);
+
+    // Display the label:
+    if (node.label && typeof node.label === 'string') {
+      context.fillStyle = (settings('labelHoverColor') === 'node') ?
+        (node.color || settings('defaultNodeColor')) :
+        settings('defaultLabelHoverColor');
+
+      context.fillText(
+        node.label,
+        Math.round(node[prefix + 'x'] + size + 3),
+        Math.round(node[prefix + 'y'] + fontSize / 3)
+      );
+    }
+  };
+}).call(this);
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.nodes');
+
+  /**
+   * The default node renderer. It renders the node as a simple disc.
+   *
+   * @param  {object}                   node     The node object.
+   * @param  {CanvasRenderingContext2D} context  The canvas context.
+   * @param  {configurable}             settings The settings function.
+   */
+  sigma.canvas.nodes.def = function(node, context, settings) {
+    var prefix = settings('prefix') || '';
+
+    context.fillStyle = node.color || settings('defaultNodeColor');
+    context.beginPath();
+    context.arc(
+      node[prefix + 'x'],
+      node[prefix + 'y'],
+      node[prefix + 'size'],
+      0,
+      Math.PI * 2,
+      true
+    );
+
+    context.closePath();
+    context.fill();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edges');
+
+  /**
+   * The default edge renderer. It renders the edge as a simple line.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edges.def = function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        size = edge[prefix + 'size'] || 1,
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor');
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(
+      source[prefix + 'x'],
+      source[prefix + 'y']
+    );
+    context.lineTo(
+      target[prefix + 'x'],
+      target[prefix + 'y']
+    );
+    context.stroke();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edges');
+
+  /**
+   * This edge renderer will display edges as curves.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edges.curve = function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        size = edge[prefix + 'size'] || 1,
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        cp = {},
+        sSize = source[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'];
+
+    cp = (source.id === target.id) ?
+      sigma.utils.getSelfLoopControlPoints(sX, sY, sSize) :
+      sigma.utils.getQuadraticControlPoint(sX, sY, tX, tY);
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    if (source.id === target.id) {
+      context.bezierCurveTo(cp.x1, cp.y1, cp.x2, cp.y2, tX, tY);
+    } else {
+      context.quadraticCurveTo(cp.x, cp.y, tX, tY);
+    }
+    context.stroke();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edges');
+
+  /**
+   * This edge renderer will display edges as arrows going from the source node
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edges.arrow = function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        size = edge[prefix + 'size'] || 1,
+        tSize = target[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'],
+        aSize = Math.max(size * 2.5, settings('minArrowSize')),
+        d = Math.sqrt(Math.pow(tX - sX, 2) + Math.pow(tY - sY, 2)),
+        aX = sX + (tX - sX) * (d - aSize - tSize) / d,
+        aY = sY + (tY - sY) * (d - aSize - tSize) / d,
+        vX = (tX - sX) * aSize / d,
+        vY = (tY - sY) * aSize / d;
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    context.lineTo(
+      aX,
+      aY
+    );
+    context.stroke();
+
+    context.fillStyle = color;
+    context.beginPath();
+    context.moveTo(aX + vX, aY + vY);
+    context.lineTo(aX + vY * 0.6, aY - vX * 0.6);
+    context.lineTo(aX - vY * 0.6, aY + vX * 0.6);
+    context.lineTo(aX + vX, aY + vY);
+    context.closePath();
+    context.fill();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edges');
+
+  /**
+   * This edge renderer will display edges as curves with arrow heading.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edges.curvedArrow =
+    function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        cp = {},
+        size = edge[prefix + 'size'] || 1,
+        tSize = target[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'],
+        aSize = Math.max(size * 2.5, settings('minArrowSize')),
+        d,
+        aX,
+        aY,
+        vX,
+        vY;
+
+    cp = (source.id === target.id) ?
+      sigma.utils.getSelfLoopControlPoints(sX, sY, tSize) :
+      sigma.utils.getQuadraticControlPoint(sX, sY, tX, tY);
+
+    if (source.id === target.id) {
+      d = Math.sqrt(Math.pow(tX - cp.x1, 2) + Math.pow(tY - cp.y1, 2));
+      aX = cp.x1 + (tX - cp.x1) * (d - aSize - tSize) / d;
+      aY = cp.y1 + (tY - cp.y1) * (d - aSize - tSize) / d;
+      vX = (tX - cp.x1) * aSize / d;
+      vY = (tY - cp.y1) * aSize / d;
+    }
+    else {
+      d = Math.sqrt(Math.pow(tX - cp.x, 2) + Math.pow(tY - cp.y, 2));
+      aX = cp.x + (tX - cp.x) * (d - aSize - tSize) / d;
+      aY = cp.y + (tY - cp.y) * (d - aSize - tSize) / d;
+      vX = (tX - cp.x) * aSize / d;
+      vY = (tY - cp.y) * aSize / d;
+    }
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    if (source.id === target.id) {
+      context.bezierCurveTo(cp.x2, cp.y2, cp.x1, cp.y1, aX, aY);
+    } else {
+      context.quadraticCurveTo(cp.x, cp.y, aX, aY);
+    }
+    context.stroke();
+
+    context.fillStyle = color;
+    context.beginPath();
+    context.moveTo(aX + vX, aY + vY);
+    context.lineTo(aX + vY * 0.6, aY - vX * 0.6);
+    context.lineTo(aX - vY * 0.6, aY + vX * 0.6);
+    context.lineTo(aX + vX, aY + vY);
+    context.closePath();
+    context.fill();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edgehovers');
+
+  /**
+   * This hover renderer will display the edge with a different color or size.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edgehovers.def =
+    function(edge, source, target, context, settings) {
+      var color = edge.color,
+        prefix = settings('prefix') || '',
+        size = edge[prefix + 'size'] || 1,
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor');
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    if (settings('edgeHoverColor') === 'edge') {
+      color = edge.hover_color || color;
+    } else {
+      color = edge.hover_color || settings('defaultEdgeHoverColor') || color;
+    }
+    size *= settings('edgeHoverSizeRatio');
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(
+      source[prefix + 'x'],
+      source[prefix + 'y']
+    );
+    context.lineTo(
+      target[prefix + 'x'],
+      target[prefix + 'y']
+    );
+    context.stroke();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edgehovers');
+
+  /**
+   * This hover renderer will display the edge with a different color or size.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edgehovers.curve =
+    function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        size = settings('edgeHoverSizeRatio') * (edge[prefix + 'size'] || 1),
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        cp = {},
+        sSize = source[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'];
+
+    cp = (source.id === target.id) ?
+      sigma.utils.getSelfLoopControlPoints(sX, sY, sSize) :
+      sigma.utils.getQuadraticControlPoint(sX, sY, tX, tY);
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    if (settings('edgeHoverColor') === 'edge') {
+      color = edge.hover_color || color;
+    } else {
+      color = edge.hover_color || settings('defaultEdgeHoverColor') || color;
+    }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    if (source.id === target.id) {
+      context.bezierCurveTo(cp.x1, cp.y1, cp.x2, cp.y2, tX, tY);
+    } else {
+      context.quadraticCurveTo(cp.x, cp.y, tX, tY);
+    }
+    context.stroke();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edgehovers');
+
+  /**
+   * This hover renderer will display the edge with a different color or size.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edgehovers.arrow =
+    function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        size = edge[prefix + 'size'] || 1,
+        tSize = target[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'];
+
+    size = (edge.hover) ?
+      settings('edgeHoverSizeRatio') * size : size;
+    var aSize = size * 2.5,
+        d = Math.sqrt(Math.pow(tX - sX, 2) + Math.pow(tY - sY, 2)),
+        aX = sX + (tX - sX) * (d - aSize - tSize) / d,
+        aY = sY + (tY - sY) * (d - aSize - tSize) / d,
+        vX = (tX - sX) * aSize / d,
+        vY = (tY - sY) * aSize / d;
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    if (settings('edgeHoverColor') === 'edge') {
+      color = edge.hover_color || color;
+    } else {
+      color = edge.hover_color || settings('defaultEdgeHoverColor') || color;
+    }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    context.lineTo(
+      aX,
+      aY
+    );
+    context.stroke();
+
+    context.fillStyle = color;
+    context.beginPath();
+    context.moveTo(aX + vX, aY + vY);
+    context.lineTo(aX + vY * 0.6, aY - vX * 0.6);
+    context.lineTo(aX - vY * 0.6, aY + vX * 0.6);
+    context.lineTo(aX + vX, aY + vY);
+    context.closePath();
+    context.fill();
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.canvas.edgehovers');
+
+  /**
+   * This hover renderer will display the edge with a different color or size.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.edgehovers.curvedArrow =
+    function(edge, source, target, context, settings) {
+    var color = edge.color,
+        prefix = settings('prefix') || '',
+        edgeColor = settings('edgeColor'),
+        defaultNodeColor = settings('defaultNodeColor'),
+        defaultEdgeColor = settings('defaultEdgeColor'),
+        cp = {},
+        size = settings('edgeHoverSizeRatio') * (edge[prefix + 'size'] || 1),
+        tSize = target[prefix + 'size'],
+        sX = source[prefix + 'x'],
+        sY = source[prefix + 'y'],
+        tX = target[prefix + 'x'],
+        tY = target[prefix + 'y'],
+        d,
+        aSize,
+        aX,
+        aY,
+        vX,
+        vY;
+
+    cp = (source.id === target.id) ?
+      sigma.utils.getSelfLoopControlPoints(sX, sY, tSize) :
+      sigma.utils.getQuadraticControlPoint(sX, sY, tX, tY);
+
+    if (source.id === target.id) {
+      d = Math.sqrt(Math.pow(tX - cp.x1, 2) + Math.pow(tY - cp.y1, 2));
+      aSize = size * 2.5;
+      aX = cp.x1 + (tX - cp.x1) * (d - aSize - tSize) / d;
+      aY = cp.y1 + (tY - cp.y1) * (d - aSize - tSize) / d;
+      vX = (tX - cp.x1) * aSize / d;
+      vY = (tY - cp.y1) * aSize / d;
+    }
+    else {
+      d = Math.sqrt(Math.pow(tX - cp.x, 2) + Math.pow(tY - cp.y, 2));
+      aSize = size * 2.5;
+      aX = cp.x + (tX - cp.x) * (d - aSize - tSize) / d;
+      aY = cp.y + (tY - cp.y) * (d - aSize - tSize) / d;
+      vX = (tX - cp.x) * aSize / d;
+      vY = (tY - cp.y) * aSize / d;
+    }
+
+    if (!color)
+      switch (edgeColor) {
+        case 'source':
+          color = source.color || defaultNodeColor;
+          break;
+        case 'target':
+          color = target.color || defaultNodeColor;
+          break;
+        default:
+          color = defaultEdgeColor;
+          break;
+      }
+
+    if (settings('edgeHoverColor') === 'edge') {
+      color = edge.hover_color || color;
+    } else {
+      color = edge.hover_color || settings('defaultEdgeHoverColor') || color;
+    }
+
+    context.strokeStyle = color;
+    context.lineWidth = size;
+    context.beginPath();
+    context.moveTo(sX, sY);
+    if (source.id === target.id) {
+      context.bezierCurveTo(cp.x2, cp.y2, cp.x1, cp.y1, aX, aY);
+    } else {
+      context.quadraticCurveTo(cp.x, cp.y, aX, aY);
+    }
+    context.stroke();
+
+    context.fillStyle = color;
+    context.beginPath();
+    context.moveTo(aX + vX, aY + vY);
+    context.lineTo(aX + vY * 0.6, aY - vX * 0.6);
+    context.lineTo(aX - vY * 0.6, aY + vX * 0.6);
+    context.lineTo(aX + vX, aY + vY);
+    context.closePath();
+    context.fill();
+  };
+})();
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.canvas.extremities');
+
+  /**
+   * The default renderer for hovered edge extremities. It renders the edge
+   * extremities as hovered.
+   *
+   * @param  {object}                   edge         The edge object.
+   * @param  {object}                   source node  The edge source node.
+   * @param  {object}                   target node  The edge target node.
+   * @param  {CanvasRenderingContext2D} context      The canvas context.
+   * @param  {configurable}             settings     The settings function.
+   */
+  sigma.canvas.extremities.def =
+    function(edge, source, target, context, settings) {
+    // Source Node:
+    (
+      sigma.canvas.hovers[source.type] ||
+      sigma.canvas.hovers.def
+    ) (
+      source, context, settings
+    );
+
+    // Target Node:
+    (
+      sigma.canvas.hovers[target.type] ||
+      sigma.canvas.hovers.def
+    ) (
+      target, context, settings
+    );
+  };
+}).call(this);
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.svg.utils');
+
+  /**
+   * Some useful functions used by sigma's SVG renderer.
+   */
+  sigma.svg.utils = {
+
+    /**
+     * SVG Element show.
+     *
+     * @param  {DOMElement}               element   The DOM element to show.
+     */
+    show: function(element) {
+      element.style.display = '';
+      return this;
+    },
+
+    /**
+     * SVG Element hide.
+     *
+     * @param  {DOMElement}               element   The DOM element to hide.
+     */
+    hide: function(element) {
+      element.style.display = 'none';
+      return this;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.svg.nodes');
+
+  /**
+   * The default node renderer. It renders the node as a simple disc.
+   */
+  sigma.svg.nodes.def = {
+
+    /**
+     * SVG Element creation.
+     *
+     * @param  {object}                   node     The node object.
+     * @param  {configurable}             settings The settings function.
+     */
+    create: function(node, settings) {
+      var prefix = settings('prefix') || '',
+          circle = document.createElementNS(settings('xmlns'), 'circle');
+
+      // Defining the node's circle
+      circle.setAttributeNS(null, 'data-node-id', node.id);
+      circle.setAttributeNS(null, 'class', settings('classPrefix') + '-node');
+      circle.setAttributeNS(
+        null, 'fill', node.color || settings('defaultNodeColor'));
+
+      // Returning the DOM Element
+      return circle;
+    },
+
+    /**
+     * SVG Element update.
+     *
+     * @param  {object}                   node     The node object.
+     * @param  {DOMElement}               circle   The node DOM element.
+     * @param  {configurable}             settings The settings function.
+     */
+    update: function(node, circle, settings) {
+      var prefix = settings('prefix') || '';
+
+      // Applying changes
+      // TODO: optimize - check if necessary
+      circle.setAttributeNS(null, 'cx', node[prefix + 'x']);
+      circle.setAttributeNS(null, 'cy', node[prefix + 'y']);
+      circle.setAttributeNS(null, 'r', node[prefix + 'size']);
+
+      // Updating only if not freestyle
+      if (!settings('freeStyle'))
+        circle.setAttributeNS(
+          null, 'fill', node.color || settings('defaultNodeColor'));
+
+      // Showing
+      circle.style.display = '';
+
+      return this;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.svg.edges');
+
+  /**
+   * The default edge renderer. It renders the node as a simple line.
+   */
+  sigma.svg.edges.def = {
+
+    /**
+     * SVG Element creation.
+     *
+     * @param  {object}                   edge       The edge object.
+     * @param  {object}                   source     The source node object.
+     * @param  {object}                   target     The target node object.
+     * @param  {configurable}             settings   The settings function.
+     */
+    create: function(edge, source, target, settings) {
+      var color = edge.color,
+          prefix = settings('prefix') || '',
+          edgeColor = settings('edgeColor'),
+          defaultNodeColor = settings('defaultNodeColor'),
+          defaultEdgeColor = settings('defaultEdgeColor');
+
+      if (!color)
+        switch (edgeColor) {
+          case 'source':
+            color = source.color || defaultNodeColor;
+            break;
+          case 'target':
+            color = target.color || defaultNodeColor;
+            break;
+          default:
+            color = defaultEdgeColor;
+            break;
+        }
+
+      var line = document.createElementNS(settings('xmlns'), 'line');
+
+      // Attributes
+      line.setAttributeNS(null, 'data-edge-id', edge.id);
+      line.setAttributeNS(null, 'class', settings('classPrefix') + '-edge');
+      line.setAttributeNS(null, 'stroke', color);
+
+      return line;
+    },
+
+    /**
+     * SVG Element update.
+     *
+     * @param  {object}                   edge       The edge object.
+     * @param  {DOMElement}               line       The line DOM Element.
+     * @param  {object}                   source     The source node object.
+     * @param  {object}                   target     The target node object.
+     * @param  {configurable}             settings   The settings function.
+     */
+    update: function(edge, line, source, target, settings) {
+      var prefix = settings('prefix') || '';
+
+      line.setAttributeNS(null, 'stroke-width', edge[prefix + 'size'] || 1);
+      line.setAttributeNS(null, 'x1', source[prefix + 'x']);
+      line.setAttributeNS(null, 'y1', source[prefix + 'y']);
+      line.setAttributeNS(null, 'x2', target[prefix + 'x']);
+      line.setAttributeNS(null, 'y2', target[prefix + 'y']);
+
+      // Showing
+      line.style.display = '';
+
+      return this;
+    }
+  };
+})();
+
+;(function() {
+  'use strict';
+
+  sigma.utils.pkg('sigma.svg.edges');
+
+  /**
+   * The curve edge renderer. It renders the node as a bezier curve.
+   */
+  sigma.svg.edges.curve = {
+
+    /**
+     * SVG Element creation.
+     *
+     * @param  {object}                   edge       The edge object.
+     * @param  {object}                   source     The source node object.
+     * @param  {object}                   target     The target node object.
+     * @param  {configurable}             settings   The settings function.
+     */
+    create: function(edge, source, target, settings) {
+      var color = edge.color,
+          prefix = settings('prefix') || '',
+          edgeColor = settings('edgeColor'),
+          defaultNodeColor = settings('defaultNodeColor'),
+          defaultEdgeColor = settings('defaultEdgeColor');
+
+      if (!color)
+        switch (edgeColor) {
+          case 'source':
+            color = source.color || defaultNodeColor;
+            break;
+          case 'target':
+            color = target.color || defaultNodeColor;
+            break;
+          default:
+            color = defaultEdgeColor;
+            break;
+        }
+
+      var path = document.createElementNS(settings('xmlns'), 'path');
+
+      // Attributes
+      path.setAttributeNS(null, 'data-edge-id', edge.id);
+      path.setAttributeNS(null, 'class', settings('classPrefix') + '-edge');
+      path.setAttributeNS(null, 'stroke', color);
+
+      return path;
+    },
+
+    /**
+     * SVG Element update.
+     *
+     * @param  {object}                   edge       The edge object.
+     * @param  {DOMElement}               line       The line DOM Element.
+     * @param  {object}                   source     The source node object.
+     * @param  {object}                   target     The target node object.
+     * @param  {configurable}             settings   The settings function.
+     */
+    update: function(edge, path, source, target, settings) {
+      var prefix = settings('prefix') || '';
+
+      path.setAttributeNS(null, 'stroke-width', edge[prefix + 'size'] || 1);
+
+      // Control point
+      var cx = (source[prefix + 'x'] + target[prefix + 'x']) / 2 +
+        (target[prefix + 'y'] - source[prefix + 'y']) / 4,
+          cy = (source[prefix + 'y'] + target[prefix + 'y']) / 2 +
+        (source[prefix + 'x'] - target[prefix + 'x']) / 4;
+
+      // Path
+      var p = 'M' + source[prefix + 'x'] + ',' + source[prefix + 'y'] + ' ' +
+              'Q' + cx + ',' + cy + ' ' +
+              target[prefix + 'x'] + ',' + target[prefix + 'y'];
+
+      // Updating attributes
+      path.setAttributeNS(null, 'd', p);
+      path.setAttributeNS(null, 'fill', 'none');
+
+      // Showing
+      path.style.display = '';
+
+      return this;
+    }
+  };
+})();
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.svg.labels');
+
+  /**
+   * The default label renderer. It renders the label as a simple text.
+   */
+  sigma.svg.labels.def = {
+
+    /**
+     * SVG Element creation.
+     *
+     * @param  {object}                   node       The node object.
+     * @param  {configurable}             settings   The settings function.
+     */
+    create: function(node, settings) {
+      var prefix = settings('prefix') || '',
+          size = node[prefix + 'size'],
+          text = document.createElementNS(settings('xmlns'), 'text');
+
+      var fontSize = (settings('labelSize') === 'fixed') ?
+        settings('defaultLabelSize') :
+        settings('labelSizeRatio') * size;
+
+      var fontColor = (settings('labelColor') === 'node') ?
+        (node.color || settings('defaultNodeColor')) :
+        settings('defaultLabelColor');
+
+      text.setAttributeNS(null, 'data-label-target', node.id);
+      text.setAttributeNS(null, 'class', settings('classPrefix') + '-label');
+      text.setAttributeNS(null, 'font-size', fontSize);
+      text.setAttributeNS(null, 'font-family', settings('font'));
+      text.setAttributeNS(null, 'fill', fontColor);
+
+      text.innerHTML = node.label;
+      text.textContent = node.label;
+
+      return text;
+    },
+
+    /**
+     * SVG Element update.
+     *
+     * @param  {object}                   node     The node object.
+     * @param  {DOMElement}               text     The label DOM element.
+     * @param  {configurable}             settings The settings function.
+     */
+    update: function(node, text, settings) {
+      var prefix = settings('prefix') || '',
+          size = node[prefix + 'size'];
+
+      var fontSize = (settings('labelSize') === 'fixed') ?
+        settings('defaultLabelSize') :
+        settings('labelSizeRatio') * size;
+
+      // Case when we don't want to display the label
+      if (!settings('forceLabels') && size < settings('labelThreshold'))
+        return;
+
+      if (typeof node.label !== 'string')
+        return;
+
+      // Updating
+      text.setAttributeNS(null, 'x',
+        Math.round(node[prefix + 'x'] + size + 3));
+      text.setAttributeNS(null, 'y',
+        Math.round(node[prefix + 'y'] + fontSize / 3));
+
+      // Showing
+      text.style.display = '';
+
+      return this;
+    }
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.svg.hovers');
+
+  /**
+   * The default hover renderer.
+   */
+  sigma.svg.hovers.def = {
+
+    /**
+     * SVG Element creation.
+     *
+     * @param  {object}           node               The node object.
+     * @param  {CanvasElement}    measurementCanvas  A fake canvas handled by
+     *                            the svg to perform some measurements and
+     *                            passed by the renderer.
+     * @param  {DOMElement}       nodeCircle         The node DOM Element.
+     * @param  {configurable}     settings           The settings function.
+     */
+    create: function(node, nodeCircle, measurementCanvas, settings) {
+
+      // Defining visual properties
+      var x,
+          y,
+          w,
+          h,
+          e,
+          d,
+          fontStyle = settings('hoverFontStyle') || settings('fontStyle'),
+          prefix = settings('prefix') || '',
+          size = node[prefix + 'size'],
+          fontSize = (settings('labelSize') === 'fixed') ?
+            settings('defaultLabelSize') :
+            settings('labelSizeRatio') * size,
+          fontColor = (settings('labelHoverColor') === 'node') ?
+                        (node.color || settings('defaultNodeColor')) :
+                        settings('defaultLabelHoverColor');
+
+      // Creating elements
+      var group = document.createElementNS(settings('xmlns'), 'g'),
+          rectangle = document.createElementNS(settings('xmlns'), 'rect'),
+          circle = document.createElementNS(settings('xmlns'), 'circle'),
+          text = document.createElementNS(settings('xmlns'), 'text');
+
+      // Defining properties
+      group.setAttributeNS(null, 'class', settings('classPrefix') + '-hover');
+      group.setAttributeNS(null, 'data-node-id', node.id);
+
+      if (typeof node.label === 'string') {
+
+        // Text
+        text.innerHTML = node.label;
+        text.textContent = node.label;
+        text.setAttributeNS(
+            null,
+            'class',
+            settings('classPrefix') + '-hover-label');
+        text.setAttributeNS(null, 'font-size', fontSize);
+        text.setAttributeNS(null, 'font-family', settings('font'));
+        text.setAttributeNS(null, 'fill', fontColor);
+        text.setAttributeNS(null, 'x',
+          Math.round(node[prefix + 'x'] + size + 3));
+        text.setAttributeNS(null, 'y',
+          Math.round(node[prefix + 'y'] + fontSize / 3));
+
+        // Measures
+        // OPTIMIZE: Find a better way than a measurement canvas
+        x = Math.round(node[prefix + 'x'] - fontSize / 2 - 2);
+        y = Math.round(node[prefix + 'y'] - fontSize / 2 - 2);
+        w = Math.round(
+          measurementCanvas.measureText(node.label).width +
+            fontSize / 2 + size + 9
+        );
+        h = Math.round(fontSize + 4);
+        e = Math.round(fontSize / 2 + 2);
+
+        // Circle
+        circle.setAttributeNS(
+            null,
+            'class',
+            settings('classPrefix') + '-hover-area');
+        circle.setAttributeNS(null, 'fill', '#fff');
+        circle.setAttributeNS(null, 'cx', node[prefix + 'x']);
+        circle.setAttributeNS(null, 'cy', node[prefix + 'y']);
+        circle.setAttributeNS(null, 'r', e);
+
+        // Rectangle
+        rectangle.setAttributeNS(
+            null,
+            'class',
+            settings('classPrefix') + '-hover-area');
+        rectangle.setAttributeNS(null, 'fill', '#fff');
+        rectangle.setAttributeNS(null, 'x', node[prefix + 'x'] + e / 4);
+        rectangle.setAttributeNS(null, 'y', node[prefix + 'y'] - e);
+        rectangle.setAttributeNS(null, 'width', w);
+        rectangle.setAttributeNS(null, 'height', h);
+      }
+
+      // Appending childs
+      group.appendChild(circle);
+      group.appendChild(rectangle);
+      group.appendChild(text);
+      group.appendChild(nodeCircle);
+
+      return group;
+    }
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.middlewares');
+  sigma.utils.pkg('sigma.utils');
+
+  /**
+   * This middleware will rescale the graph such that it takes an optimal space
+   * on the renderer.
+   *
+   * As each middleware, this function is executed in the scope of the sigma
+   * instance.
+   *
+   * @param {?string} readPrefix  The read prefix.
+   * @param {?string} writePrefix The write prefix.
+   * @param {object}  options     The parameters.
+   */
+  sigma.middlewares.rescale = function(readPrefix, writePrefix, options) {
+    var i,
+        l,
+        a,
+        b,
+        c,
+        d,
+        scale,
+        margin,
+        n = this.graph.nodes(),
+        e = this.graph.edges(),
+        settings = this.settings.embedObjects(options || {}),
+        bounds = settings('bounds') || sigma.utils.getBoundaries(
+          this.graph,
+          readPrefix,
+          true
+        ),
+        minX = bounds.minX,
+        minY = bounds.minY,
+        maxX = bounds.maxX,
+        maxY = bounds.maxY,
+        sizeMax = bounds.sizeMax,
+        weightMax = bounds.weightMax,
+        w = settings('width') || 1,
+        h = settings('height') || 1,
+        rescaleSettings = settings('autoRescale'),
+        validSettings = {
+          nodePosition: 1,
+          nodeSize: 1,
+          edgeSize: 1
+        };
+
+    /**
+     * What elements should we rescale?
+     */
+    if (!(rescaleSettings instanceof Array))
+      rescaleSettings = ['nodePosition', 'nodeSize', 'edgeSize'];
+
+    for (i = 0, l = rescaleSettings.length; i < l; i++)
+      if (!validSettings[rescaleSettings[i]])
+        throw new Error(
+          'The rescale setting "' + rescaleSettings[i] + '" is not recognized.'
+        );
+
+    var np = ~rescaleSettings.indexOf('nodePosition'),
+        ns = ~rescaleSettings.indexOf('nodeSize'),
+        es = ~rescaleSettings.indexOf('edgeSize');
+
+    /**
+     * First, we compute the scaling ratio, without considering the sizes
+     * of the nodes : Each node will have its center in the canvas, but might
+     * be partially out of it.
+     */
+    scale = settings('scalingMode') === 'outside' ?
+      Math.max(
+        w / Math.max(maxX - minX, 1),
+        h / Math.max(maxY - minY, 1)
+      ) :
+      Math.min(
+        w / Math.max(maxX - minX, 1),
+        h / Math.max(maxY - minY, 1)
+      );
+
+    /**
+     * Then, we correct that scaling ratio considering a margin, which is
+     * basically the size of the biggest node.
+     * This has to be done as a correction since to compare the size of the
+     * biggest node to the X and Y values, we have to first get an
+     * approximation of the scaling ratio.
+     **/
+    margin =
+      (
+        settings('rescaleIgnoreSize') ?
+          0 :
+          (settings('maxNodeSize') || sizeMax) / scale
+      ) +
+      (settings('sideMargin') || 0);
+    maxX += margin;
+    minX -= margin;
+    maxY += margin;
+    minY -= margin;
+
+    // Fix the scaling with the new extrema:
+    scale = settings('scalingMode') === 'outside' ?
+      Math.max(
+        w / Math.max(maxX - minX, 1),
+        h / Math.max(maxY - minY, 1)
+      ) :
+      Math.min(
+        w / Math.max(maxX - minX, 1),
+        h / Math.max(maxY - minY, 1)
+      );
+
+    // Size homothetic parameters:
+    if (!settings('maxNodeSize') && !settings('minNodeSize')) {
+      a = 1;
+      b = 0;
+    } else if (settings('maxNodeSize') === settings('minNodeSize')) {
+      a = 0;
+      b = +settings('maxNodeSize');
+    } else {
+      a = (settings('maxNodeSize') - settings('minNodeSize')) / sizeMax;
+      b = +settings('minNodeSize');
+    }
+
+    if (!settings('maxEdgeSize') && !settings('minEdgeSize')) {
+      c = 1;
+      d = 0;
+    } else if (settings('maxEdgeSize') === settings('minEdgeSize')) {
+      c = 0;
+      d = +settings('minEdgeSize');
+    } else {
+      c = (settings('maxEdgeSize') - settings('minEdgeSize')) / weightMax;
+      d = +settings('minEdgeSize');
+    }
+
+    // Rescale the nodes and edges:
+    for (i = 0, l = e.length; i < l; i++)
+      e[i][writePrefix + 'size'] =
+        e[i][readPrefix + 'size'] * (es ? c : 1) + (es ? d : 0);
+
+    for (i = 0, l = n.length; i < l; i++) {
+      n[i][writePrefix + 'size'] =
+        n[i][readPrefix + 'size'] * (ns ? a : 1) + (ns ? b : 0);
+      n[i][writePrefix + 'x'] =
+        (n[i][readPrefix + 'x'] - (maxX + minX) / 2) * (np ? scale : 1);
+      n[i][writePrefix + 'y'] =
+        (n[i][readPrefix + 'y'] - (maxY + minY) / 2) * (np ? scale : 1);
+    }
+  };
+
+  sigma.utils.getBoundaries = function(graph, prefix, doEdges) {
+    var i,
+        l,
+        e = graph.edges(),
+        n = graph.nodes(),
+        weightMax = -Infinity,
+        sizeMax = -Infinity,
+        minX = Infinity,
+        minY = Infinity,
+        maxX = -Infinity,
+        maxY = -Infinity;
+
+    if (doEdges)
+      for (i = 0, l = e.length; i < l; i++)
+        weightMax = Math.max(e[i][prefix + 'size'], weightMax);
+
+    for (i = 0, l = n.length; i < l; i++) {
+      sizeMax = Math.max(n[i][prefix + 'size'], sizeMax);
+      maxX = Math.max(n[i][prefix + 'x'], maxX);
+      minX = Math.min(n[i][prefix + 'x'], minX);
+      maxY = Math.max(n[i][prefix + 'y'], maxY);
+      minY = Math.min(n[i][prefix + 'y'], minY);
+    }
+
+    weightMax = weightMax || 1;
+    sizeMax = sizeMax || 1;
+
+    return {
+      weightMax: weightMax,
+      sizeMax: sizeMax,
+      minX: minX,
+      minY: minY,
+      maxX: maxX,
+      maxY: maxY
+    };
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.middlewares');
+
+  /**
+   * This middleware will just copy the graphic properties.
+   *
+   * @param {?string} readPrefix  The read prefix.
+   * @param {?string} writePrefix The write prefix.
+   */
+  sigma.middlewares.copy = function(readPrefix, writePrefix) {
+    var i,
+        l,
+        a;
+
+    if (writePrefix + '' === readPrefix + '')
+      return;
+
+    a = this.graph.nodes();
+    for (i = 0, l = a.length; i < l; i++) {
+      a[i][writePrefix + 'x'] = a[i][readPrefix + 'x'];
+      a[i][writePrefix + 'y'] = a[i][readPrefix + 'y'];
+      a[i][writePrefix + 'size'] = a[i][readPrefix + 'size'];
+    }
+
+    a = this.graph.edges();
+    for (i = 0, l = a.length; i < l; i++)
+      a[i][writePrefix + 'size'] = a[i][readPrefix + 'size'];
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.misc.animation.running');
+
+  /**
+   * Generates a unique ID for the animation.
+   *
+   * @return {string} Returns the new ID.
+   */
+  var _getID = (function() {
+    var id = 0;
+    return function() {
+      return '' + (++id);
+    };
+  })();
+
+  /**
+   * This function animates a camera. It has to be called with the camera to
+   * animate, the values of the coordinates to reach and eventually some
+   * options. It returns a number id, that you can use to kill the animation,
+   * with the method sigma.misc.animation.kill(id).
+   *
+   * The available options are:
+   *
+   *   {?number}            duration   The duration of the animation.
+   *   {?function}          onNewFrame A callback to execute when the animation
+   *                                   enter a new frame.
+   *   {?function}          onComplete A callback to execute when the animation
+   *                                   is completed or killed.
+   *   {?(string|function)} easing     The name of a function from the package
+   *                                   sigma.utils.easings, or a custom easing
+   *                                   function.
+   *
+   * @param  {camera}  camera  The camera to animate.
+   * @param  {object}  target  The coordinates to reach.
+   * @param  {?object} options Eventually an object to specify some options to
+   *                           the function. The available options are
+   *                           presented in the description of the function.
+   * @return {number}          The animation id, to make it easy to kill
+   *                           through the method "sigma.misc.animation.kill".
+   */
+  sigma.misc.animation.camera = function(camera, val, options) {
+    if (
+      !(camera instanceof sigma.classes.camera) ||
+      typeof val !== 'object' ||
+      !val
+    )
+      throw 'animation.camera: Wrong arguments.';
+
+    if (
+      typeof val.x !== 'number' &&
+      typeof val.y !== 'number' &&
+      typeof val.ratio !== 'number' &&
+      typeof val.angle !== 'number'
+    )
+      throw 'There must be at least one valid coordinate in the given val.';
+
+    var fn,
+        id,
+        anim,
+        easing,
+        duration,
+        initialVal,
+        o = options || {},
+        start = sigma.utils.dateNow();
+
+    // Store initial values:
+    initialVal = {
+      x: camera.x,
+      y: camera.y,
+      ratio: camera.ratio,
+      angle: camera.angle
+    };
+
+    duration = o.duration;
+    easing = typeof o.easing !== 'function' ?
+      sigma.utils.easings[o.easing || 'quadraticInOut'] :
+      o.easing;
+
+    fn = function() {
+      var coef,
+          t = o.duration ? (sigma.utils.dateNow() - start) / o.duration : 1;
+
+      // If the animation is over:
+      if (t >= 1) {
+        camera.isAnimated = false;
+        camera.goTo({
+          x: val.x !== undefined ? val.x : initialVal.x,
+          y: val.y !== undefined ? val.y : initialVal.y,
+          ratio: val.ratio !== undefined ? val.ratio : initialVal.ratio,
+          angle: val.angle !== undefined ? val.angle : initialVal.angle
+        });
+
+        cancelAnimationFrame(id);
+        delete sigma.misc.animation.running[id];
+
+        // Check callbacks:
+        if (typeof o.onComplete === 'function')
+          o.onComplete();
+
+      // Else, let's keep going:
+      } else {
+        coef = easing(t);
+        camera.isAnimated = true;
+        camera.goTo({
+          x: val.x !== undefined ?
+            initialVal.x + (val.x - initialVal.x) * coef :
+            initialVal.x,
+          y: val.y !== undefined ?
+            initialVal.y + (val.y - initialVal.y) * coef :
+            initialVal.y,
+          ratio: val.ratio !== undefined ?
+            initialVal.ratio + (val.ratio - initialVal.ratio) * coef :
+            initialVal.ratio,
+          angle: val.angle !== undefined ?
+            initialVal.angle + (val.angle - initialVal.angle) * coef :
+            initialVal.angle
+        });
+
+        // Check callbacks:
+        if (typeof o.onNewFrame === 'function')
+          o.onNewFrame();
+
+        anim.frameId = requestAnimationFrame(fn);
+      }
+    };
+
+    id = _getID();
+    anim = {
+      frameId: requestAnimationFrame(fn),
+      target: camera,
+      type: 'camera',
+      options: o,
+      fn: fn
+    };
+    sigma.misc.animation.running[id] = anim;
+
+    return id;
+  };
+
+  /**
+   * Kills a running animation. It triggers the eventual onComplete callback.
+   *
+   * @param  {number} id  The id of the animation to kill.
+   * @return {object}     Returns the sigma.misc.animation package.
+   */
+  sigma.misc.animation.kill = function(id) {
+    if (arguments.length !== 1 || typeof id !== 'number')
+      throw 'animation.kill: Wrong arguments.';
+
+    var o = sigma.misc.animation.running[id];
+
+    if (o) {
+      cancelAnimationFrame(id);
+      delete sigma.misc.animation.running[o.frameId];
+
+      if (o.type === 'camera')
+        o.target.isAnimated = false;
+
+      // Check callbacks:
+      if (typeof (o.options || {}).onComplete === 'function')
+        o.options.onComplete();
+    }
+
+    return this;
+  };
+
+  /**
+   * Kills every running animations, or only the one with the specified type,
+   * if a string parameter is given.
+   *
+   * @param  {?(string|object)} filter A string to filter the animations to kill
+   *                                   on their type (example: "camera"), or an
+   *                                   object to filter on their target.
+   * @return {number}                  Returns the number of animations killed
+   *                                   that way.
+   */
+  sigma.misc.animation.killAll = function(filter) {
+    var o,
+        id,
+        count = 0,
+        type = typeof filter === 'string' ? filter : null,
+        target = typeof filter === 'object' ? filter : null,
+        running = sigma.misc.animation.running;
+
+    for (id in running)
+      if (
+        (!type || running[id].type === type) &&
+        (!target || running[id].target === target)
+      ) {
+        o = sigma.misc.animation.running[id];
+        cancelAnimationFrame(o.frameId);
+        delete sigma.misc.animation.running[id];
+
+        if (o.type === 'camera')
+          o.target.isAnimated = false;
+
+        // Increment counter:
+        count++;
+
+        // Check callbacks:
+        if (typeof (o.options || {}).onComplete === 'function')
+          o.options.onComplete();
+      }
+
+    return count;
+  };
+
+  /**
+   * Returns "true" if any animation that is currently still running matches
+   * the filter given to the function.
+   *
+   * @param  {string|object} filter A string to filter the animations to kill
+   *                                on their type (example: "camera"), or an
+   *                                object to filter on their target.
+   * @return {boolean}              Returns true if any running animation
+   *                                matches.
+   */
+  sigma.misc.animation.has = function(filter) {
+    var id,
+        type = typeof filter === 'string' ? filter : null,
+        target = typeof filter === 'object' ? filter : null,
+        running = sigma.misc.animation.running;
+
+    for (id in running)
+      if (
+        (!type || running[id].type === type) &&
+        (!target || running[id].target === target)
+      )
+        return true;
+
+    return false;
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.misc');
+
+  /**
+   * This helper will bind any no-DOM renderer (for instance canvas or WebGL)
+   * to its captors, to properly dispatch the good events to the sigma instance
+   * to manage clicking, hovering etc...
+   *
+   * It has to be called in the scope of the related renderer.
+   */
+  sigma.misc.bindEvents = function(prefix) {
+    var i,
+        l,
+        mX,
+        mY,
+        captor,
+        self = this;
+
+    function getNodes(e) {
+      if (e) {
+        mX = 'x' in e.data ? e.data.x : mX;
+        mY = 'y' in e.data ? e.data.y : mY;
+      }
+
+      var i,
+          j,
+          l,
+          n,
+          x,
+          y,
+          s,
+          inserted,
+          selected = [],
+          modifiedX = mX + self.width / 2,
+          modifiedY = mY + self.height / 2,
+          point = self.camera.cameraPosition(
+            mX,
+            mY
+          ),
+          nodes = self.camera.quadtree.point(
+            point.x,
+            point.y
+          );
+
+      if (nodes.length)
+        for (i = 0, l = nodes.length; i < l; i++) {
+          n = nodes[i];
+          x = n[prefix + 'x'];
+          y = n[prefix + 'y'];
+          s = n[prefix + 'size'];
+
+          if (
+            !n.hidden &&
+            modifiedX > x - s &&
+            modifiedX < x + s &&
+            modifiedY > y - s &&
+            modifiedY < y + s &&
+            Math.sqrt(
+              Math.pow(modifiedX - x, 2) +
+              Math.pow(modifiedY - y, 2)
+            ) < s
+          ) {
+            // Insert the node:
+            inserted = false;
+
+            for (j = 0; j < selected.length; j++)
+              if (n.size > selected[j].size) {
+                selected.splice(j, 0, n);
+                inserted = true;
+                break;
+              }
+
+            if (!inserted)
+              selected.push(n);
+          }
+        }
+
+      return selected;
+    }
+
+
+    function getEdges(e) {
+      if (!self.settings('enableEdgeHovering')) {
+        // No event if the setting is off:
+        return [];
+      }
+
+      var isCanvas = (
+        sigma.renderers.canvas && self instanceof sigma.renderers.canvas);
+
+      if (!isCanvas) {
+        // A quick hardcoded rule to prevent people from using this feature
+        // with the WebGL renderer (which is not good enough at the moment):
+        throw new Error(
+          'The edge events feature is not compatible with the WebGL renderer'
+        );
+      }
+
+      if (e) {
+        mX = 'x' in e.data ? e.data.x : mX;
+        mY = 'y' in e.data ? e.data.y : mY;
+      }
+
+      var i,
+          j,
+          l,
+          a,
+          edge,
+          s,
+          maxEpsilon = self.settings('edgeHoverPrecision'),
+          source,
+          target,
+          cp,
+          nodeIndex = {},
+          inserted,
+          selected = [],
+          modifiedX = mX + self.width / 2,
+          modifiedY = mY + self.height / 2,
+          point = self.camera.cameraPosition(
+            mX,
+            mY
+          ),
+          edges = [];
+
+      if (isCanvas) {
+        var nodesOnScreen = self.camera.quadtree.area(
+          self.camera.getRectangle(self.width, self.height)
+        );
+        for (a = nodesOnScreen, i = 0, l = a.length; i < l; i++)
+          nodeIndex[a[i].id] = a[i];
+      }
+
+      if (self.camera.edgequadtree !== undefined) {
+        edges = self.camera.edgequadtree.point(
+          point.x,
+          point.y
+        );
+      }
+
+      function insertEdge(selected, edge) {
+        inserted = false;
+
+        for (j = 0; j < selected.length; j++)
+          if (edge.size > selected[j].size) {
+            selected.splice(j, 0, edge);
+            inserted = true;
+            break;
+          }
+
+        if (!inserted)
+          selected.push(edge);
+      }
+
+      if (edges.length)
+        for (i = 0, l = edges.length; i < l; i++) {
+          edge = edges[i];
+          source = self.graph.nodes(edge.source);
+          target = self.graph.nodes(edge.target);
+          // (HACK) we can't get edge[prefix + 'size'] on WebGL renderer:
+          s = edge[prefix + 'size'] ||
+              edge['read_' + prefix + 'size'];
+
+          // First, let's identify which edges are drawn. To do this, we keep
+          // every edges that have at least one extremity displayed according to
+          // the quadtree and the "hidden" attribute. We also do not keep hidden
+          // edges.
+          // Then, let's check if the mouse is on the edge (we suppose that it
+          // is a line segment).
+
+          if (
+            !edge.hidden &&
+            !source.hidden && !target.hidden &&
+            (!isCanvas ||
+              (nodeIndex[edge.source] || nodeIndex[edge.target])) &&
+            sigma.utils.getDistance(
+              source[prefix + 'x'],
+              source[prefix + 'y'],
+              modifiedX,
+              modifiedY) > source[prefix + 'size'] &&
+            sigma.utils.getDistance(
+              target[prefix + 'x'],
+              target[prefix + 'y'],
+              modifiedX,
+              modifiedY) > target[prefix + 'size']
+          ) {
+            if (edge.type == 'curve' || edge.type == 'curvedArrow') {
+              if (source.id === target.id) {
+                cp = sigma.utils.getSelfLoopControlPoints(
+                  source[prefix + 'x'],
+                  source[prefix + 'y'],
+                  source[prefix + 'size']
+                );
+                if (
+                  sigma.utils.isPointOnBezierCurve(
+                  modifiedX,
+                  modifiedY,
+                  source[prefix + 'x'],
+                  source[prefix + 'y'],
+                  target[prefix + 'x'],
+                  target[prefix + 'y'],
+                  cp.x1,
+                  cp.y1,
+                  cp.x2,
+                  cp.y2,
+                  Math.max(s, maxEpsilon)
+                )) {
+                  insertEdge(selected, edge);
+                }
+              }
+              else {
+                cp = sigma.utils.getQuadraticControlPoint(
+                  source[prefix + 'x'],
+                  source[prefix + 'y'],
+                  target[prefix + 'x'],
+                  target[prefix + 'y']);
+                if (
+                  sigma.utils.isPointOnQuadraticCurve(
+                  modifiedX,
+                  modifiedY,
+                  source[prefix + 'x'],
+                  source[prefix + 'y'],
+                  target[prefix + 'x'],
+                  target[prefix + 'y'],
+                  cp.x,
+                  cp.y,
+                  Math.max(s, maxEpsilon)
+                )) {
+                  insertEdge(selected, edge);
+                }
+              }
+            } else if (
+                sigma.utils.isPointOnSegment(
+                modifiedX,
+                modifiedY,
+                source[prefix + 'x'],
+                source[prefix + 'y'],
+                target[prefix + 'x'],
+                target[prefix + 'y'],
+                Math.max(s, maxEpsilon)
+              )) {
+              insertEdge(selected, edge);
+            }
+          }
+        }
+
+      return selected;
+    }
+
+
+    function bindCaptor(captor) {
+      var nodes,
+          edges,
+          overNodes = {},
+          overEdges = {};
+
+      function onClick(e) {
+        if (!self.settings('eventsEnabled'))
+          return;
+
+        self.dispatchEvent('click', e.data);
+
+        nodes = getNodes(e);
+        edges = getEdges(e);
+
+        if (nodes.length) {
+          self.dispatchEvent('clickNode', {
+            node: nodes[0],
+            captor: e.data
+          });
+          self.dispatchEvent('clickNodes', {
+            node: nodes,
+            captor: e.data
+          });
+        } else if (edges.length) {
+          self.dispatchEvent('clickEdge', {
+            edge: edges[0],
+            captor: e.data
+          });
+          self.dispatchEvent('clickEdges', {
+            edge: edges,
+            captor: e.data
+          });
+        } else
+          self.dispatchEvent('clickStage', {captor: e.data});
+      }
+
+      function onDoubleClick(e) {
+        if (!self.settings('eventsEnabled'))
+          return;
+
+        self.dispatchEvent('doubleClick', e.data);
+
+        nodes = getNodes(e);
+        edges = getEdges(e);
+
+        if (nodes.length) {
+          self.dispatchEvent('doubleClickNode', {
+            node: nodes[0],
+            captor: e.data
+          });
+          self.dispatchEvent('doubleClickNodes', {
+            node: nodes,
+            captor: e.data
+          });
+        } else if (edges.length) {
+          self.dispatchEvent('doubleClickEdge', {
+            edge: edges[0],
+            captor: e.data
+          });
+          self.dispatchEvent('doubleClickEdges', {
+            edge: edges,
+            captor: e.data
+          });
+        } else
+          self.dispatchEvent('doubleClickStage', {captor: e.data});
+      }
+
+      function onRightClick(e) {
+        if (!self.settings('eventsEnabled'))
+          return;
+
+        self.dispatchEvent('rightClick', e.data);
+
+        nodes = getNodes(e);
+        edges = getEdges(e);
+
+        if (nodes.length) {
+          self.dispatchEvent('rightClickNode', {
+            node: nodes[0],
+            captor: e.data
+          });
+          self.dispatchEvent('rightClickNodes', {
+            node: nodes,
+            captor: e.data
+          });
+        } else if (edges.length) {
+          self.dispatchEvent('rightClickEdge', {
+            edge: edges[0],
+            captor: e.data
+          });
+          self.dispatchEvent('rightClickEdges', {
+            edge: edges,
+            captor: e.data
+          });
+        } else
+          self.dispatchEvent('rightClickStage', {captor: e.data});
+      }
+
+      function onOut(e) {
+        if (!self.settings('eventsEnabled'))
+          return;
+
+        var k,
+            i,
+            l,
+            le,
+            outNodes = [],
+            outEdges = [];
+
+        for (k in overNodes)
+          outNodes.push(overNodes[k]);
+
+        overNodes = {};
+        // Dispatch both single and multi events:
+        for (i = 0, l = outNodes.length; i < l; i++)
+          self.dispatchEvent('outNode', {
+            node: outNodes[i],
+            captor: e.data
+          });
+        if (outNodes.length)
+          self.dispatchEvent('outNodes', {
+            nodes: outNodes,
+            captor: e.data
+          });
+
+        overEdges = {};
+        // Dispatch both single and multi events:
+        for (i = 0, le = outEdges.length; i < le; i++)
+          self.dispatchEvent('outEdge', {
+            edge: outEdges[i],
+            captor: e.data
+          });
+        if (outEdges.length)
+          self.dispatchEvent('outEdges', {
+            edges: outEdges,
+            captor: e.data
+          });
+      }
+
+      function onMove(e) {
+        if (!self.settings('eventsEnabled'))
+          return;
+
+        nodes = getNodes(e);
+        edges = getEdges(e);
+
+        var i,
+            k,
+            node,
+            edge,
+            newOutNodes = [],
+            newOverNodes = [],
+            currentOverNodes = {},
+            l = nodes.length,
+            newOutEdges = [],
+            newOverEdges = [],
+            currentOverEdges = {},
+            le = edges.length;
+
+        // Check newly overred nodes:
+        for (i = 0; i < l; i++) {
+          node = nodes[i];
+          currentOverNodes[node.id] = node;
+          if (!overNodes[node.id]) {
+            newOverNodes.push(node);
+            overNodes[node.id] = node;
+          }
+        }
+
+        // Check no more overred nodes:
+        for (k in overNodes)
+          if (!currentOverNodes[k]) {
+            newOutNodes.push(overNodes[k]);
+            delete overNodes[k];
+          }
+
+        // Dispatch both single and multi events:
+        for (i = 0, l = newOverNodes.length; i < l; i++)
+          self.dispatchEvent('overNode', {
+            node: newOverNodes[i],
+            captor: e.data
+          });
+        for (i = 0, l = newOutNodes.length; i < l; i++)
+          self.dispatchEvent('outNode', {
+            node: newOutNodes[i],
+            captor: e.data
+          });
+        if (newOverNodes.length)
+          self.dispatchEvent('overNodes', {
+            nodes: newOverNodes,
+            captor: e.data
+          });
+        if (newOutNodes.length)
+          self.dispatchEvent('outNodes', {
+            nodes: newOutNodes,
+            captor: e.data
+          });
+
+        // Check newly overred edges:
+        for (i = 0; i < le; i++) {
+          edge = edges[i];
+          currentOverEdges[edge.id] = edge;
+          if (!overEdges[edge.id]) {
+            newOverEdges.push(edge);
+            overEdges[edge.id] = edge;
+          }
+        }
+
+        // Check no more overred edges:
+        for (k in overEdges)
+          if (!currentOverEdges[k]) {
+            newOutEdges.push(overEdges[k]);
+            delete overEdges[k];
+          }
+
+        // Dispatch both single and multi events:
+        for (i = 0, le = newOverEdges.length; i < le; i++)
+          self.dispatchEvent('overEdge', {
+            edge: newOverEdges[i],
+            captor: e.data
+          });
+        for (i = 0, le = newOutEdges.length; i < le; i++)
+          self.dispatchEvent('outEdge', {
+            edge: newOutEdges[i],
+            captor: e.data
+          });
+        if (newOverEdges.length)
+          self.dispatchEvent('overEdges', {
+            edges: newOverEdges,
+            captor: e.data
+          });
+        if (newOutEdges.length)
+          self.dispatchEvent('outEdges', {
+            edges: newOutEdges,
+            captor: e.data
+          });
+      }
+
+      // Bind events:
+      captor.bind('click', onClick);
+      captor.bind('mousedown', onMove);
+      captor.bind('mouseup', onMove);
+      captor.bind('mousemove', onMove);
+      captor.bind('mouseout', onOut);
+      captor.bind('doubleclick', onDoubleClick);
+      captor.bind('rightclick', onRightClick);
+      self.bind('render', onMove);
+    }
+
+    for (i = 0, l = this.captors.length; i < l; i++)
+      bindCaptor(this.captors[i]);
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.misc');
+
+  /**
+   * This helper will bind any DOM renderer (for instance svg)
+   * to its captors, to properly dispatch the good events to the sigma instance
+   * to manage clicking, hovering etc...
+   *
+   * It has to be called in the scope of the related renderer.
+   */
+  sigma.misc.bindDOMEvents = function(container) {
+    var self = this,
+        graph = this.graph;
+
+    // DOMElement abstraction
+    function Element(domElement) {
+
+      // Helpers
+      this.attr = function(attrName) {
+        return domElement.getAttributeNS(null, attrName);
+      };
+
+      // Properties
+      this.tag = domElement.tagName;
+      this.class = this.attr('class');
+      this.id = this.attr('id');
+
+      // Methods
+      this.isNode = function() {
+        return !!~this.class.indexOf(self.settings('classPrefix') + '-node');
+      };
+
+      this.isEdge = function() {
+        return !!~this.class.indexOf(self.settings('classPrefix') + '-edge');
+      };
+
+      this.isHover = function() {
+        return !!~this.class.indexOf(self.settings('classPrefix') + '-hover');
+      };
+    }
+
+    // Click
+    function click(e) {
+      if (!self.settings('eventsEnabled'))
+        return;
+
+      // Generic event
+      self.dispatchEvent('click', e);
+
+      // Are we on a node?
+      var element = new Element(e.target);
+
+      if (element.isNode())
+        self.dispatchEvent('clickNode', {
+          node: graph.nodes(element.attr('data-node-id'))
+        });
+      else
+        self.dispatchEvent('clickStage');
+
+      e.preventDefault();
+      e.stopPropagation();
+    }
+
+    // Double click
+    function doubleClick(e) {
+      if (!self.settings('eventsEnabled'))
+        return;
+
+      // Generic event
+      self.dispatchEvent('doubleClick', e);
+
+      // Are we on a node?
+      var element = new Element(e.target);
+
+      if (element.isNode())
+        self.dispatchEvent('doubleClickNode', {
+          node: graph.nodes(element.attr('data-node-id'))
+        });
+      else
+        self.dispatchEvent('doubleClickStage');
+
+      e.preventDefault();
+      e.stopPropagation();
+    }
+
+    // On over
+    function onOver(e) {
+      var target = e.toElement || e.target;
+
+      if (!self.settings('eventsEnabled') || !target)
+        return;
+
+      var el = new Element(target);
+
+      if (el.isNode()) {
+        self.dispatchEvent('overNode', {
+          node: graph.nodes(el.attr('data-node-id'))
+        });
+      }
+      else if (el.isEdge()) {
+        var edge = graph.edges(el.attr('data-edge-id'));
+        self.dispatchEvent('overEdge', {
+          edge: edge,
+          source: graph.nodes(edge.source),
+          target: graph.nodes(edge.target)
+        });
+      }
+    }
+
+    // On out
+    function onOut(e) {
+      var target = e.fromElement || e.originalTarget;
+
+      if (!self.settings('eventsEnabled'))
+        return;
+
+      var el = new Element(target);
+
+      if (el.isNode()) {
+        self.dispatchEvent('outNode', {
+          node: graph.nodes(el.attr('data-node-id'))
+        });
+      }
+      else if (el.isEdge()) {
+        var edge = graph.edges(el.attr('data-edge-id'));
+        self.dispatchEvent('outEdge', {
+          edge: edge,
+          source: graph.nodes(edge.source),
+          target: graph.nodes(edge.target)
+        });
+      }
+    }
+
+    // Registering Events:
+
+    // Click
+    container.addEventListener('click', click, false);
+    sigma.utils.doubleClick(container, 'click', doubleClick);
+
+    // Touch counterparts
+    container.addEventListener('touchstart', click, false);
+    sigma.utils.doubleClick(container, 'touchstart', doubleClick);
+
+    // Mouseover
+    container.addEventListener('mouseover', onOver, true);
+
+    // Mouseout
+    container.addEventListener('mouseout', onOut, true);
+  };
+}).call(this);
+
+;(function(undefined) {
+  'use strict';
+
+  if (typeof sigma === 'undefined')
+    throw 'sigma is not declared';
+
+  // Initialize packages:
+  sigma.utils.pkg('sigma.misc');
+
+  /**
+   * This method listens to "overNode", "outNode", "overEdge" and "outEdge"
+   * events from a renderer and renders the nodes differently on the top layer.
+   * The goal is to make any node label readable with the mouse, and to
+   * highlight hovered nodes and edges.
+   *
+   * It has to be called in the scope of the related renderer.
+   */
+  sigma.misc.drawHovers = function(prefix) {
+    var self = this,
+        hoveredNodes = {},
+        hoveredEdges = {};
+
+    this.bind('overNode', function(event) {
+      var node = event.data.node;
+      if (!node.hidden) {
+        hoveredNodes[node.id] = node;
+        draw();
+      }
+    });
+
+    this.bind('outNode', function(event) {
+      delete hoveredNodes[event.data.node.id];
+      draw();
+    });
+
+    this.bind('overEdge', function(event) {
+      var edge = event.data.edge;
+      if (!edge.hidden) {
+        hoveredEdges[edge.id] = edge;
+        draw();
+      }
+    });
+
+    this.bind('outEdge', function(event) {
+      delete hoveredEdges[event.data.edge.id];
+      draw();
+    });
+
+    this.bind('render', function(event) {
+      draw();
+    });
+
+    function draw() {
+
+      var k,
+          source,
+          target,
+          hoveredNode,
+          hoveredEdge,
+          c = self.contexts.hover.canvas,
+          defaultNodeType = self.settings('defaultNodeType'),
+          defaultEdgeType = self.settings('defaultEdgeType'),
+          nodeRenderers = sigma.canvas.hovers,
+          edgeRenderers = sigma.canvas.edgehovers,
+          extremitiesRenderers = sigma.canvas.extremities,
+          embedSettings = self.settings.embedObjects({
+            prefix: prefix
+          });
+
+      // Clear self.contexts.hover:
+      self.contexts.hover.clearRect(0, 0, c.width, c.height);
+
+      // Node render: single hover
+      if (
+        embedSettings('enableHovering') &&
+        embedSettings('singleHover') &&
+        Object.keys(hoveredNodes).length
+      ) {
+        hoveredNode = hoveredNodes[Object.keys(hoveredNodes)[0]];
+        (
+          nodeRenderers[hoveredNode.type] ||
+          nodeRenderers[defaultNodeType] ||
+          nodeRenderers.def
+        )(
+          hoveredNode,
+          self.contexts.hover,
+          embedSettings
+        );
+      }
+
+      // Node render: multiple hover
+      if (
+        embedSettings('enableHovering') &&
+        !embedSettings('singleHover')
+      )
+        for (k in hoveredNodes)
+          (
+            nodeRenderers[hoveredNodes[k].type] ||
+            nodeRenderers[defaultNodeType] ||
+            nodeRenderers.def
+          )(
+            hoveredNodes[k],
+            self.contexts.hover,
+            embedSettings
+          );
+
+      // Edge render: single hover
+      if (
+        embedSettings('enableEdgeHovering') &&
+        embedSettings('singleHover') &&
+        Object.keys(hoveredEdges).length
+      ) {
+        hoveredEdge = hoveredEdges[Object.keys(hoveredEdges)[0]];
+        source = self.graph.nodes(hoveredEdge.source);
+        target = self.graph.nodes(hoveredEdge.target);
+
+        if (! hoveredEdge.hidden) {
+          (
+            edgeRenderers[hoveredEdge.type] ||
+            edgeRenderers[defaultEdgeType] ||
+            edgeRenderers.def
+          ) (
+            hoveredEdge,
+            source,
+            target,
+            self.contexts.hover,
+            embedSettings
+          );
+
+          if (embedSettings('edgeHoverExtremities')) {
+            (
+              extremitiesRenderers[hoveredEdge.type] ||
+              extremitiesRenderers.def
+            )(
+              hoveredEdge,
+              source,
+              target,
+              self.contexts.hover,
+              embedSettings
+            );
+
+          } else {
+            // Avoid edges rendered over nodes:
+            (
+              sigma.canvas.nodes[source.type] ||
+              sigma.canvas.nodes.def
+            ) (
+              source,
+              self.contexts.hover,
+              embedSettings
+            );
+            (
+              sigma.canvas.nodes[target.type] ||
+              sigma.canvas.nodes.def
+            ) (
+              target,
+              self.contexts.hover,
+              embedSettings
+            );
+          }
+        }
+      }
+
+      // Edge render: multiple hover
+      if (
+        embedSettings('enableEdgeHovering') &&
+        !embedSettings('singleHover')
+      ) {
+        for (k in hoveredEdges) {
+          hoveredEdge = hoveredEdges[k];
+          source = self.graph.nodes(hoveredEdge.source);
+          target = self.graph.nodes(hoveredEdge.target);
+
+          if (!hoveredEdge.hidden) {
+            (
+              edgeRenderers[hoveredEdge.type] ||
+              edgeRenderers[defaultEdgeType] ||
+              edgeRenderers.def
+            ) (
+              hoveredEdge,
+              source,
+              target,
+              self.contexts.hover,
+              embedSettings
+            );
+
+            if (embedSettings('edgeHoverExtremities')) {
+              (
+                extremitiesRenderers[hoveredEdge.type] ||
+                extremitiesRenderers.def
+              )(
+                hoveredEdge,
+                source,
+                target,
+                self.contexts.hover,
+                embedSettings
+              );
+            } else {
+              // Avoid edges rendered over nodes:
+              (
+                sigma.canvas.nodes[source.type] ||
+                sigma.canvas.nodes.def
+              ) (
+                source,
+                self.contexts.hover,
+                embedSettings
+              );
+              (
+                sigma.canvas.nodes[target.type] ||
+                sigma.canvas.nodes.def
+              ) (
+                target,
+                self.contexts.hover,
+                embedSettings
+              );
+            }
+          }
+        }
+      }
+    }
+  };
+}).call(this);
diff --git a/openo-portal/portal-lifecyclemgr/overlayvpn_topo.html b/openo-portal/portal-lifecyclemgr/overlayvpn_topo.html
new file mode 100644
index 0000000..610e0b5
--- /dev/null
+++ b/openo-portal/portal-lifecyclemgr/overlayvpn_topo.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+  #container {
+      top: 0;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      position: absolute;
+  }
+</style>
+</head>
+<body>
+<div id="container"></div>
+<script src="js/topo/sigma/sigma.min.js"></script>
+<script src="js/topo/sigma/jquery-3.1.0.min.js"></script>
+<script src="js/topo/sigma/plugins/sigma.renderers.customShapes.min.js"></script>
+<script src="js/topo/sigma/plugins/sigma.renderers.edgeLabels.min.js"></script>
+<script src="js/topo/Node.js"></script>
+<script src="js/topo/Edge.js"></script>
+<script src="js/topo/Topology.js"></script>
+</body>
+</html>
\ No newline at end of file
