From ffdce0d6ddd965f773ca9b328ed7701bc0e2b91a Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 14:56:49 +0200 Subject: [PATCH 01/21] =?UTF-8?q?Classization=20du=20sociogramme=20(js/inc?= =?UTF-8?q?ludes/sociogram.js)=20+=20gestion=20de=20l'include=20d=C3=A9j?= =?UTF-8?q?=C3=A0=20charg=C3=A9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/includes/sociogram.js | 1071 ++++++++++++++++++++++++++++++++++++++ js/includes/test.js | 1 - js/lib/page-manager.js | 20 +- js/lib/reset.js | 54 +- tags | 15 +- view/charts.php | 2 +- view/js/charts.js | 412 +-------------- 7 files changed, 1154 insertions(+), 421 deletions(-) create mode 100644 js/includes/sociogram.js delete mode 100644 js/includes/test.js diff --git a/js/includes/sociogram.js b/js/includes/sociogram.js new file mode 100644 index 0000000..8aee70e --- /dev/null +++ b/js/includes/sociogram.js @@ -0,0 +1,1071 @@ +/* Gestion du SOCIOGRAMME SPATIAL +* +* [1] - Récupération du conteneur (élément du DOM/HTML) +* [2] - Construction de la classe (objet type) +* [3] - Construction de l'objet SIGMA +* [4] - Récupération des données +* [5] - Paramétrage de SIGMA +* [6] - On extrait les noeuds/liens des données reçues +* [7] - On ajoute les noeuds/liens à SIGMA +* [8] - On positionne le tout dans l'espace +* [9] - On bind() les évènements +* [10]- On affiche le rendu +* +*/ + +/* [1] Récupération du conteneur +=========================================================*/ +function sociogramClass(container){ + this.container = container; + this.log('sociogram created'); +}; + + + + + +/* [2] Construction de la classe +=========================================================*/ +sociogramClass.prototype = { + container: this.container, + sigma: null, + request: { path: 'charts/network_data' }, + response: null, + nodes: [], + edges: [], + rad: 500, + nodeDistance: 100, + + /* (0) Ajout de méthodes à @this.sigma.graph */ + overloadGraph: function(){}, + + /* (1) Point d'amorçage */ + load: function(){}, + + /* (2) Retourne la distance avec le noeud le plus près de la position (@x, @y) */ + nodeAt: function(x, y){}, + /* (3) Positionnement spatial d'un noeud d'id @nodeId à une position @pos(x,y) */ + arrange: function(nodeId, pos, alone){}, + + /* (4) Extraction de des @this.nodes depuis @this.response */ + extractNodesFromResponse: function(){}, + /* (5) Extraction de des @this.edges depuis @this.response */ + extractEdgesFromResponse: function(){}, + + /* (6) Ajout des noeuds @this.nodes au rendu */ + renderNodes: function(){}, + /* (7) Ajout des liens @this.edges au rendu */ + renderEdges: function(){}, + + /* (8) Ajout des fonctions dans @this.sigma.graph */ + overload: { + // {1} Renvoie la liste des voisins directs et indirects du noeud d'id @nodeId // + nodeNeighbors: function(nodeId){}, + // {2} Renvoie la liste des voisins directs du noeud d'id @nodeId // + nodeDirectNeighbors: function(nodeId){} + }, + + /* (9) Fonctions de callback pour les évènements */ + bindings: { + // {1} Action quand on clique sur un noeud // + clickNode: function(thisPtr, e){}, + // {2} Action quand on clique dans le vide // + clickStage: function(thisPtr, e){} + }, + + + log: function(message){ + console.log('--[SOCIOGRAM]--'); + console.warn(message); + console.log('--[/SOCIOGRAM]--'); + } + +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* SURCHARGE DU GRAPH (@this.sigma.graph) -> Ajout de méthodes +* +*/ +sociogramClass.prototype.overloadGraph = function(){ + sigma.classes.graph.addMethod('nodeNeighbors', this.overload.nodeNeighbors); + sigma.classes.graph.addMethod('nodeDirectNeighbors', this.overload.nodeDirectNeighbors); + this.log('graph overloaded'); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* (1) Point d'amorçage */ +sociogramClass.prototype.load = function(){ + // {1} On instancie SIGMA // + this.sigma = new sigma({ renderer: { container: this.container, 'type': 'canvas' } }); + + var thisPtr = this; + + // {2} On récupère les données via l'API // + api.send(this.request, function(response){ + thisPtr.log(response); + + // Si erreur, on quitte + if( response.ModuleError != 0 ) return; + + // On enregistre la réponse + thisPtr.response = response; + + + // {3} On paramètre SIGMA // + thisPtr.sigma.settings({ + defaultNodeColor: '#348ed8', + defaultLabelSize: 14, + defaultLabelBGColor: "#ddd", + defaultHoverLabelBGColor: "#002147", + defaultLabelHoverColor: "#fff", + labelThreshold: 10, + defaultEdgeType: "line" + }); + + // {4} On recupere les noeuds et les liens // + thisPtr.extractNodesFromResponse(); + thisPtr.extractEdgesFromResponse(); + + // {5} On ajoute les noeuds et les liens au rendu // + thisPtr.addNodes(); + thisPtr.addEdges(); + + + // {6} On définit les évènements // + // On affiche que les voisins d'un noeud quand on clique sur lui + thisPtr.sigma.bind('clickNode', function(e){ + thisPtr.bindings.clickNode(thisPtr, e); + }); + + // On affiche tous les noeuds quand on clique dans le vide + thisPtr.sigma.bind('clickStage', function(e){ + thisPtr.bindings.clickStage(thisPtr, e); + }); + + // {7} On positionne spatialement les noeuds // + thisPtr.sigma.graph.nodes().forEach(function(n){ thisPtr.arrange(n.id, null, true); }); + + // {8} On affiche le rendu // + thisPtr.sigma.camera.ratio = 1.2; + thisPtr.sigma.refresh(); + }); +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +/* RETOURNE LA DISTANCE AVEC LE NOEUD LE PLUS PRES +* +* @x Abscisse du point +* @y Ordonnees du point +* +* @return distance Retourne la distance du noeud le plus proche +* +*/ +sociogramClass.prototype.nodeAt = function(x, y){ + var nodes = this.sigma.graph.nodes(); + var minDistance = null; + + for( nodeId in nodes ){ + var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); + if( minDistance == null || distance < minDistance ) + minDistance = distance; + } + + return minDistance; +}; + + + + + + + + + + + + + + + +/* POSITIONNE LES VOISINS AUTOUR DU NOEUD COURANT +* +* @nodeId Id du noeud courant +* @pos Contient {x, y} position initiale, sinon la position actuelle du noeud +* +*/ +sociogramClass.prototype.arrange = function(nodeId, pos, alone){ + var node = this.sigma.graph.nodes(nodeId); + + // Si le noeud est deja place, on ne fais rien + if( node.x != 0 || node.y != 0 ) return; + + var pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position + + // Tant que le noeud est trop proche d'un autre, on l'eloigne + // UNIQUEMENT si alone n'est pas NULL + if( alone ){ + while( this.nodeAt(pos.x, pos.y) < 2*this.nodeDistance ){ + pos = { + x: pos.x + 2*this.nodeDistance*Math.cos(Math.random()*2*Math.PI), + y: pos.y + 2*this.nodeDistance*Math.sin(Math.random()*2*Math.PI) + }; + + + + + + + + + + + + + } + } + + // On recupere les voisins directs + var neighborsId = this.sigma.graph.nodeDirectNeighbors(nodeId); + var neighbors = {}; + + + + + + + + + + + + + var neighborsCount = 0; + for( neighborId in neighborsId ){ + neighbors[neighborId] = this.sigma.graph.nodes(neighborId); + neighborsCount++; + } + + + // On positionne le noeud + node.x = pos.x; + node.y = pos.y; + + var angles = []; + + // On positionne chaque voisin si c'est pas deja fait + for( neighborId in neighbors ){ + var current = this.sigma.graph.nodes(neighborId); + // Si n'est pas deja positionne + if( current.x == 0 && current.y == 0 ){ + // On cherche un angle tant qu'il est pas trop pres d'un deja pris + var angle, alreadyUsed = false; + do{ + angle = Math.random()*2*Math.PI; + for( var i = 0 ; i < angles.length ; i++ ) + if( Math.abs(angle-angles[i]) > Math.PI/10 ){ + alreadyUsed = true; + break; + } + + }while( alreadyUsed ); + + current.x = pos.x + this.nodeDistance*Math.cos(angle); + current.y = pos.y + this.nodeDistance*Math.sin(angle); + this.arrange(current.id); + } + } + + this.sigma.refresh(); +}; + + + + + + + + + + + + + + + + +/* RENVOIE LA LISTE DES VOISINS (DIRECTS & INDIRECTS) D'UN NOEUD DONNÉ +* +* @nodeId Id du noeud en question +* +* @return neighbors Liste des voisins directs+indirects +* +*/ +sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){ + var neighbors = this.allNeighborsIndex[nodeId]; + + // Pile des voisins pour lesquels il faut chercher leurs voisins + var stack = []; + for( neighborId in neighbors ) stack.push(neighborId); + + // Tant qu'il reste des voisins a trouver + while( stack.length > 0 ){ + var subneighbors = this.allNeighborsIndex[stack[0]]; + for( subId in subneighbors ) + // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins + if( neighbors[subId] == null ){ + stack.push(subId); // On ajoute a la pile + neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete + } + + stack.shift(); + } + + + // On retourne le resultat + return neighbors; +}; + + + + + + + + + + + + + + + +/* RENVOIE LA LISTE DES VOISINS DIRECTS D'UN NOEUD DONNÉ +* +* @nodeId Id du noeud en question +* +* @return neighbors Liste des voisins directs +* +*/ +sociogramClass.prototype.overload.nodeDirectNeighbors = function(nodeId){ + return this.allNeighborsIndex[nodeId]; +}; + + + + + + + + + + + + + + + +/* EXTRAIT LES NOEUDS DE LA RÉPONSE DE L'API +* +*/ +sociogramClass.prototype.extractNodesFromResponse = function(){ + this.nodes = []; + + // Pour chaque alter + for( var i = 0 ; i < this.response.data.alter.length ; i++ ) + this.nodes.push({ + 'id': 'n-'+this.response.data.alter[i][0], + 'label': this.response.data.alter[i][1], + 'x': 0, + 'y': 0, + 'size': this.response.data.alter[i][2] + }); + +}; + + + + + + + + + + + + + + + +/* EXTRAIT LES NOEUDS DE LA RÉPONSE DE L'API +* +*/ +sociogramClass.prototype.extractEdgesFromResponse = function(){ + this.edges = []; + + // Pour chaque inter + for( var i = 0 ; i < this.response.data.inter.length ; i++ ) + this.edges.push({ + 'id': 'e-'+this.response.data.inter[i][0]+'-'+this.response.data.inter[i][1], + 'source': 'n-'+this.response.data.inter[i][0], + 'target': 'n-'+this.response.data.inter[i][1] + }); +}; + + + + + + + + + + + + + + + +/* AJOUTE LES NOEUDS AU RENDU (SIGMA GRAPH) +* +*/ +sociogramClass.prototype.addNodes = function(){ + /* (5) On ajoute nos noeuds */ + for( var i = 0 ; i < this.nodes.length ; i++) + this.sigma.graph.addNode(this.nodes[i]); +}; + + + + + + + + + + + + + + +/* AJOUTE LES LIENS AU RENDU (SIGMA GRAPH) +* +*/ +sociogramClass.prototype.addEdges = function(){ + /* (6) On ajoute nos liens */ + for( var i = 0 ; i < this.edges.length ; i++) + this.sigma.graph.addEdge(this.edges[i]); +}; + + + + + + + + + +/* FONCTION ACTIVÉE LORS DU CLIC SUR UN NOEUD +* +*/ +sociogramClass.prototype.bindings.clickNode = function(thisPtr, e){ + console.log( thisPtr ); + var nodeId = e.data.node.id; + // On recupere les voisins + var neighborNodes = thisPtr.sigma.graph.nodeNeighbors(nodeId); + neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique + + thisPtr.sigma.graph.nodes().forEach(function(n) { + if( neighborNodes[n.id] != null ) n.color = n.originalColor; + else n.color = '#eee'; + }); + + thisPtr.sigma.refresh(); +}; + + + + + + + + + + +/* FONCTION ACTIVÉE LORS DU CLIC DANS LE VIDE +* +*/ +sociogramClass.prototype.bindings.clickStage = function(thisPtr, e){ + thisPtr.sigma.graph.nodes().forEach(function(n){ n.color = n.originalColor; }); + thisPtr.sigma.refresh(); +}; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// +// +// +// /* (0.5) Surcharge graph */ +// // On recupere les voisins d'un noeud +// if( typeof sigma.classes.graph.nodeNeighbors !== 'function ') +// sigma.classes.graph.addMethod('nodeNeighbors', function(nodeId){ +// // On recupere les voisins du noeud courant +// var neighbors = this.allNeighborsIndex[nodeId]; +// +// // Pile des voisins pour lesquels il faut chercher leurs voisins +// var stack = []; +// for( neighborId in neighbors ) stack.push(neighborId); +// +// // Tant qu'il reste des voisins a trouver +// while( stack.length > 0 ){ +// var subneighbors = this.allNeighborsIndex[stack[0]]; +// for( subId in subneighbors ) +// // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins +// if( neighbors[subId] == null ){ +// stack.push(subId); // On ajoute a la pile +// neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete +// } +// +// stack.shift(); +// } +// +// +// // On retourne le resultat +// return neighbors; +// }); +// +// // On recupere les voisins directs d'un noeud +// if( typeof sigma.classes.graph.nodeDirectNeighbors !== 'function ') +// sigma.classes.graph.addMethod('nodeDirectNeighbors', function(nodeId){ +// // On retourne les voisins directs +// return this.allNeighborsIndex[nodeId]; +// }); +// +// +// +// +// +// +// +// /* (0.8) Initialisation de SIGMA */ +// SOCIOGRAM.sigma = new sigma({renderer: { container: SOCIOGRAM.container, 'type': 'canvas' }}); +// +// +// +// +// +// +// +// +// +// +// /* (1) On recupere les informations via l'API */ +// api.send(SOCIOGRAM.request, function(response){ +// console.log( response ); +// // Si erreur, on quitte +// if( response.ModuleError != 0 ) return; +// +// // Sinon on enregistre +// SOCIOGRAM.response = response; +// +// +// +// +// +// +// +// /* (2) Parametrage de SIGMA */ +// SOCIOGRAM.sigma.settings({ +// defaultNodeColor: '#348ed8', +// defaultLabelSize: 14, +// defaultLabelBGColor: "#ddd", +// defaultHoverLabelBGColor: "#002147", +// defaultLabelHoverColor: "#fff", +// labelThreshold: 10, +// defaultEdgeType: "line" +// }); +// +// +// +// +// +// +// +// /* (3) On recupere la liste des noeuds */ +// SOCIOGRAM.nodes = []; +// +// // Pour chaque alter +// for( var i = 0 ; i < SOCIOGRAM.response.data.alter.length ; i++ ){ +// SOCIOGRAM.nodes.push({ +// 'id': 'n-'+SOCIOGRAM.response.data.alter[i][0], +// 'label': SOCIOGRAM.response.data.alter[i][1], +// 'x': 0, +// 'y': 0, +// 'size': SOCIOGRAM.response.data.alter[i][2] +// }); +// } +// +// +// +// +// +// +// +// +// /* (4) On recupere la liste des liens */ +// SOCIOGRAM.edges = []; +// +// for( var i = 0 ; i < SOCIOGRAM.response.data.inter.length ; i++ ){ +// SOCIOGRAM.edges.push({ +// 'id': 'e-'+SOCIOGRAM.response.data.inter[i][0]+'-'+SOCIOGRAM.response.data.inter[i][1], +// 'source': 'n-'+SOCIOGRAM.response.data.inter[i][0], +// 'target': 'n-'+SOCIOGRAM.response.data.inter[i][1] +// }); +// } +// +// +// +// +// +// +// +// +// /* (5) On ajoute nos noeuds */ +// for( var i = 0 ; i < SOCIOGRAM.nodes.length ; i++) +// SOCIOGRAM.sigma.graph.addNode(SOCIOGRAM.nodes[i]); +// +// +// +// +// +// +// /* (6) On ajoute nos liens */ +// for( var i = 0 ; i < SOCIOGRAM.edges.length ; i++) +// SOCIOGRAM.sigma.graph.addEdge(SOCIOGRAM.edges[i]); +// +// +// +// +// +// +// /* (7) Gestion des interactions */ +// /* RETOURNE LA DISTANCE AVEC LE NOEUD LE PLUS PRES +// * +// * @x Abscisse du point +// * @y Ordonnees du point +// * +// * @return distance Retourne la distance du noeud le plus proche +// * +// */ +// SOCIOGRAM.nodeAt = function(x, y){ +// var nodes = SOCIOGRAM.sigma.graph.nodes(); +// var minDistance = null; +// +// for( nodeId in nodes ){ +// var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); +// if( minDistance == null || distance < minDistance ) +// minDistance = distance; +// } +// +// return minDistance; +// }; + + + + + + + + + + + + +// +// +// +// /* POSITIONNE LES VOISINS AUTOUR DU NOEUD COURANT +// * +// * @nodeId Id du noeud courant +// * @pos Contient {x, y} position initiale, sinon la position actuelle du noeud +// * +// */ +// SOCIOGRAM.arrange = function(nodeId, pos, alone){ +// var node = SOCIOGRAM.sigma.graph.nodes(nodeId); +// +// // Si le noeud est deja place, on ne fais rien +// if( node.x != 0 || node.y != 0 ) return; +// +// var pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position +// +// // Tant que le noeud est trop proche d'un autre, on l'eloigne +// // UNIQUEMENT si alone n'est pas NULL +// if( alone ){ +// while( SOCIOGRAM.nodeAt(pos.x, pos.y) < 2*SOCIOGRAM.nodeDistance ){ +// pos = { +// x: pos.x + 2*SOCIOGRAM.nodeDistance*Math.cos(Math.random()*2*Math.PI), +// y: pos.y + 2*SOCIOGRAM.nodeDistance*Math.sin(Math.random()*2*Math.PI) +// }; + + + + + + + + + + + + +// } +// } +// +// // On recupere les voisins directs +// var neighborsId = SOCIOGRAM.sigma.graph.nodeDirectNeighbors(nodeId); +// var neighbors = {}; + + + + + + + + + + + + +// var neighborsCount = 0; +// for( neighborId in neighborsId ){ +// neighbors[neighborId] = SOCIOGRAM.sigma.graph.nodes(neighborId); +// neighborsCount++; +// } +// +// +// // On positionne le noeud +// node.x = pos.x; +// node.y = pos.y; +// +// var angles = []; +// +// // On positionne chaque voisin si c'est pas deja fait +// for( neighborId in neighbors ){ +// var current = SOCIOGRAM.sigma.graph.nodes(neighborId); +// // Si n'est pas deja positionne +// if( current.x == 0 && current.y == 0 ){ +// // On cherche un angle tant qu'il est pas trop pres d'un deja pris +// var angle, alreadyUsed = false; +// do{ +// angle = Math.random()*2*Math.PI; +// for( var i = 0 ; i < angles.length ; i++ ) +// if( Math.abs(angle-angles[i]) > Math.PI/10 ){ +// alreadyUsed = true; +// break; +// } +// +// }while( alreadyUsed ); +// +// current.x = pos.x + SOCIOGRAM.nodeDistance*Math.cos(angle); +// current.y = pos.y + SOCIOGRAM.nodeDistance*Math.sin(angle); +// SOCIOGRAM.arrange(current.id); +// } +// } +// +// SOCIOGRAM.sigma.refresh(); +// }; + + + + + + + + + + + + +// +// // On affiche que les voisins d'un noeud +// SOCIOGRAM.sigma.bind('clickNode', function(e){ +// var nodeId = e.data.node.id; +// // On recupere les voisins +// var neighborNodes = SOCIOGRAM.sigma.graph.nodeNeighbors(nodeId); +// neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique +// +// SOCIOGRAM.sigma.graph.nodes().forEach(function(n) { +// if( neighborNodes[n.id] != null ) n.color = n.originalColor; +// else n.color = '#eee'; +// }); +// +// SOCIOGRAM.sigma.refresh(); +// }); +// +// // On affiche tous les noeuds quand on clique dans le vide +// SOCIOGRAM.sigma.bind('clickStage', function(e){ +// SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ n.color = n.originalColor; }); +// +// SOCIOGRAM.sigma.refresh(); +// }); +// +// +// +// +// +// +// /* (8) On affiche le graphique */ +// SOCIOGRAM.sigma.camera.ratio = 1.2; +// +// // On repartit les noeuds +// SOCIOGRAM.sigma.refresh(); +// SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ SOCIOGRAM.arrange(n.id, null, true); }); +// +// SOCIOGRAM.sigma.refresh(); +// +// }); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// var i, +// s, +// o, +// L = 10, +// N = 100, +// E = 500, +// g = { +// nodes: [], +// edges: [] +// }, +// step = 0; +// // Generate a random graph: +// for (i = 0; i < N; i++) { +// o = { +// id: 'n' + i, +// label: 'Node ' + i, +// circular_x: L * Math.cos(Math.PI * 2 * i / N - Math.PI / 2), +// circular_y: L * Math.sin(Math.PI * 2 * i / N - Math.PI / 2), +// circular_size: Math.random(), +// circular_color: '#' + ( +// Math.floor(Math.random() * 16777215).toString(16) + '000000' +// ).substr(0, 6), +// grid_x: i % L, +// grid_y: Math.floor(i / L), +// grid_size: 1, +// grid_color: '#ccc' +// }; + + + + + + + + + + + + +// ['x', 'y', 'size', 'color'].forEach(function(val) { +// o[val] = o['grid_' + val]; +// }); +// g.nodes.push(o); +// } +// for (i = 0; i < E; i++) +// g.edges.push({ +// id: 'e' + i, +// source: 'n' + (Math.random() * N | 0), +// target: 'n' + (Math.random() * N | 0), +// }); +// // Instantiate sigma: +// s = new sigma({ +// graph: g, +// renderer: { container: document.getElementById('graph-container'), 'type': 'canvas' }, +// settings: { +// animationsTime: 1000 +// } +// }); + +// setInterval(function(){ +// var prefix = ['grid_', 'circular_'][step = +!step]; +// sigma.plugins.animate( +// s, +// { +// x: prefix + 'x', +// y: prefix + 'y', +// size: prefix + 'size', +// color: prefix + 'color' +// } +// ); +// }, 10000); diff --git a/js/includes/test.js b/js/includes/test.js deleted file mode 100644 index 84d02ea..0000000 --- a/js/includes/test.js +++ /dev/null @@ -1 +0,0 @@ -var a = 'Hello World!'; diff --git a/js/lib/page-manager.js b/js/lib/page-manager.js index a7f2bb1..914e2b4 100755 --- a/js/lib/page-manager.js +++ b/js/lib/page-manager.js @@ -45,7 +45,7 @@ pageManagerClass.prototype = { if(window.XMLHttpRequest) // IE7+, Firefox, Chrome, Opera, Safari index = this.xhr.push( new XMLHttpRequest() ) -1; - else // IE5, IE6 + else // IE5, IE6 index = this.xhr.push( new ActiveXObject('Microsoft.XMLHttpRequest') ) -1; // On definit un pointeur sur l'instance XHR active (ajax) @@ -83,7 +83,7 @@ pageManagerClass.prototype = { // var fd = new FormData(); // création d'un formulaire // fd.append('var', 100); // ajout de la variable VAR qui vaut 100 - + // ajax( 'index.php', alert, null, fd ); // saut de paramètre avec null + envoi formulaire // ajax( 'index.php?var=10', alert, 'GET' ); // envoi formulaire en GET (dans l'url) // ajax( 'index.php?var=10', alert, 'POST', fd ); // envoi formulaire en GET (dans l'url) + en POST via le formulaire FD @@ -156,7 +156,7 @@ pageManagerClass.prototype = { }, /* ======================================================================= - Met à jour l'URL de la page en fonction de la page chargée et des + Met à jour l'URL de la page en fonction de la page chargée et des variables associées (ne recharge aucune ressource) ======================================================================= */ updateURL: function(){ @@ -205,7 +205,7 @@ pageManagerClass.prototype = { /* on attribue le paramètre pContainer à l'attribut si il est spécifié */ this.container = ( typeof pContainer == 'object' && pContainer instanceof Element ) ? pContainer : this.container; - // si this.pagelist && this.container ne sont pas null && + // si this.pagelist && this.container ne sont pas null && if( this.pagelist != null && this.container != null ){ // si le pName est renseigné et qu'il est dans pagelist if( typeof pName == 'string' && this.pagelist.indexOf(pName) > -1 ){ @@ -219,15 +219,15 @@ pageManagerClass.prototype = { var fd = new FormData(); for( var i = 0 ; i < this.vars.length ; i++ ) fd.append(this.vars[i], null); - + this.ajax(this.path+'/'+this.page+'.php', function(e){ ptrPageManagerClass.container.innerHTML = e; - ptrPageManagerClass.loadDependencies(); + ptrPageManagerClass.loadDependencies(); }, 'POST', fd); // change l'URL en conséquences(stateObj, titre, url) this.updateURL(); - + }else{ // si la page n'est pas spécifiée ou qu'elle n'est pas dans la liste des pages var urlGet = this.explodeURL(); @@ -248,12 +248,12 @@ pageManagerClass.prototype = { this.ajax(this.path+'/'+this.page+'.php', function(e){ ptrThis.container.innerHTML = e; - ptrThis.loadDependencies(); + ptrThis.loadDependencies(); }, 'POST', fd); // change l'URL en conséquences(stateObj, titre, url) this.updateURL(); - + }else // si l'url ne contient rien, on charge la page par défaut this.setPage(this.pagelist[0]); } @@ -276,4 +276,4 @@ pageManagerClass.prototype = { return this; } -} \ No newline at end of file +} diff --git a/js/lib/reset.js b/js/lib/reset.js index 25be8eb..b3e4aad 100755 --- a/js/lib/reset.js +++ b/js/lib/reset.js @@ -106,14 +106,56 @@ Element.prototype.anim = function(className, timeout){ // INCLUSION D'UN SCRIPT JAVASCRIPT -function include(jsResource, callback){ - var tag = document.createElement('script'); - tag.type = 'text/javascript'; - tag.src = jsResource; +var includes = []; +var includeTags = []; +function include(jsResource, callback, action){ // action=true -> EXCLUSION, SINON -> INCLUSION + /* (0) On formatte les arguments */ + jsResource = typeof jsResource === 'string' ? jsResource : null; + callback = typeof callback === 'function' ? callback : function(){ console.log('[x] '+jsResource+' loaded'); }; + action = typeof action === 'boolean' ? action : false; - document.head.appendChild( tag ); + // Si la ressource n'est pas donnée + if( jsResource == null ) return false; - tag.onload = callback; + + /* (1) Gestion de l'inclusion */ + if( !action ){ + // Si le fichier est déja inclus, on lance le callback + if( includes.indexOf(jsResource) > -1 ){ + callback(); + return true; + } + + // On crée l'élément dans le tag + var tag = document.createElement('script'); + tag.type = 'text/javascript'; + tag.src = jsResource; + document.head.appendChild( tag ); + + // On ajoute la ressource et le tag à la liste + includes.push(jsResource); + includeTags.push(tag); + + // On définit le callback + tag.onload = callback; + + return true; + /* (2) Gestion de l'exclusion */ + }else{ + var index = includes.indexOf(jsResource); + + // On vérifie que le fichier est déja inclus + if( index == -1 ) return false; + + // On supprime l'élément + document.head.removeChild( includeTags[index] ); + + // On dé-indexe l'élément + includes.splice(index, 1); + includeTags.splice(index, 1); + + return true; + } } diff --git a/tags b/tags index bec0ac6..9953437 100644 --- a/tags +++ b/tags @@ -3171,7 +3171,7 @@ id_user manager/repo/user.php /^ $id_user = $checkCreate->fetch();$/;" v ignore_regexes sftp-config.json /^ "ignore_regexes": [$/;" f import js/lib/sigma/plugins/sigma.plugins.filter.min.js /^(function(undefined){"use strict";function register(a,b,c){if(c!=undefined&&"string"!=typeof c)throw'The filter key "'+c.toString()+'" must be a string.';if(c!=undefined&&!c.length)throw"The filter key must be a non-empty string.";if("function"!=typeof a)throw'The predicate of key "'+c+'" must be a function.';if("undo"===c)throw'"undo" is a reserved key.';if(_keysIndex[c])throw'The filter "'+c+'" already exists.';c&&(_keysIndex[c]=!0),_chain.push({key:c,processor:a,predicate:b})}function unregister(a){_chain=_chain.filter(function(b){return!(b.key in a)});for(var b in a)delete _keysIndex[b]}function Filter(a){_s=a,_g=a.graph}function deepCopy(o){var copy=Object.create(null);for(var i in o)"object"==typeof o[i]&&null!==o[i]?copy[i]=deepCopy(o[i]):"function"==typeof o[i]&&null!==o[i]?eval(" copy[i] = "+o[i].toString()):copy[i]=o[i];return copy}function cloneChain(a){for(var b=a.slice(0),c=0,d=b.length;d>c;c++)b[c]=deepCopy(b[c]),"function"==typeof b[c].processor&&(b[c].processor="filter.processors."+b[c].processor.name);return b}if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.plugins"),sigma.classes.graph.hasMethod("adjacentNodes")||sigma.classes.graph.addMethod("adjacentNodes",function(a){if("string"!=typeof a)throw"adjacentNodes: the node id must be a string.";var b,c=[];for(b in this.allNeighborsIndex[a])c.push(this.nodesIndex[b]);return c}),sigma.classes.graph.hasMethod("adjacentEdges")||sigma.classes.graph.addMethod("adjacentEdges",function(a){if("string"!=typeof a)throw"adjacentEdges: the node id must be a string.";var b,c,d=this.allNeighborsIndex[a],e=[];for(c in d)for(b in d[c])e.push(d[c][b]);return e});var _g=undefined,_s=undefined,_chain=[],_keysIndex=Object.create(null),Processors={};Processors.nodes=function(a){for(var b=_g.nodes(),c=b.length,d=_g.edges(),e=d.length;c--;)b[c].hidden=!a.call(_g,b[c])||b[c].hidden;for(;e--;)(_g.nodes(d[e].source).hidden||_g.nodes(d[e].target).hidden)&&(d[e].hidden=!0)},Processors.edges=function(a){for(var b=_g.edges(),c=b.length;c--;)b[c].hidden=!a.call(_g,b[c])||b[c].hidden},Processors.neighbors=function a(b){for(var c=_g.nodes(),d=c.length,e=_g.edges(),f=e.length,a=_g.adjacentNodes(b),g=a.length,h={};g--;)h[a[g].id]=!0;for(;d--;)c[d].id===b||c[d].id in h||(c[d].hidden=!0);for(;f--;)(_g.nodes(e[f].source).hidden||_g.nodes(e[f].target).hidden)&&(e[f].hidden=!0)},Filter.prototype.nodesBy=function(a,b){return register(Processors.nodes,a,b),this},Filter.prototype.edgesBy=function(a,b){return register(Processors.edges,a,b),this},Filter.prototype.neighborsOf=function(a,b){if("string"!=typeof a)throw'The node id "'+a.toString()+'" must be a string.';if(!a.length)throw"The node id must be a non-empty string.";return register(Processors.neighbors,a,b),this},Filter.prototype.apply=function(){for(var a=0,b=_chain.length;b>a;++a)_chain[a].processor(_chain[a].predicate);return _chain[0]&&"undo"===_chain[0].key&&_chain.shift(),_s.refresh(),this},Filter.prototype.undo=function(a){function b(){for(var a=_g.nodes(),b=a.length,c=_g.edges(),d=c.length;b--;)a[b].hidden=!1;for(;d--;)c[d].hidden=!1}var c=Object.create(null),d=arguments.length;if(1===d)if("[object Array]"===Object.prototype.toString.call(a))for(var e=0,f=a.length;f>e;e++)c[a[e]]=!0;else c[a]=!0;else if(d>1)for(var e=0;d>e;e++)c[arguments[e]]=!0;else this.clear();return unregister(c),_chain.unshift({key:"undo",processor:b}),this},Filter.prototype.clear=function(){return _chain.length=0,_keysIndex=Object.create(null),this},Filter.prototype.export=function(){var a=cloneChain(_chain);return a},Filter.prototype.import=function(a){if(a===undefined)throw"Wrong arguments.";if("[object Array]"!==Object.prototype.toString.call(a))throw'The chain" must be an array.';for(var b=cloneChain(a),c=0,d=b.length;d>c;c++){if(b[c].predicate===undefined||b[c].processor===undefined)throw"Wrong arguments.";if(b[c].key!=undefined&&"string"!=typeof b[c].key)throw'The filter key "'+b[c].key.toString()+'" must be a string.';if("function"!=typeof b[c].predicate)throw'The predicate of key "'+b[c].key+'" must be a function.';if("string"!=typeof b[c].processor)throw'The processor of key "'+b[c].key+'" must be a string.';switch(b[c].processor){case"filter.processors.nodes":b[c].processor=Processors.nodes;break;case"filter.processors.edges":b[c].processor=Processors.edges;break;case"filter.processors.neighbors":b[c].processor=Processors.neighbors;break;default:throw"Unknown processor "+b[c].processor}}return _chain=b,this};var filter=null;sigma.plugins.filter=function(a){return filter||(filter=new Filter(a)),filter}}).call(this);/;" m inArray js/lib/highcharts/js/highcharts.src.js /^ };$/;" f -include js/lib/reset.js /^function include(jsResource, callback){$/;" f +include js/lib/reset.js /^function include(jsResource, callback, action){ \/\/ action=true -> EXCLUSION, SINON -> INCLUSION$/;" f inflate manager/MenuManager.php /^ public function inflate(){$/;" f input api/manifest.default.json /^ "input": {$/;" f inputChecker js/lib/input-checker.js /^function inputChecker(){};$/;" c @@ -3903,6 +3903,19 @@ sigma.webgl.nodes.fast.initProgram js/lib/sigma/sigma.require.js /^ },$/;" m sigma.webgl.nodes.fast.render js/lib/sigma/sigma.js /^ },$/;" m sigma.webgl.nodes.fast.render js/lib/sigma/sigma.require.js /^ },$/;" m sms automate.php /^ $sms = $answer->get('sms');$/;" v +sociogramClass js/includes/sociogram.js /^function sociogramClass(container){$/;" c +sociogramClass.addEdges js/includes/sociogram.js /^sociogramClass.prototype.addEdges = function(){$/;" m +sociogramClass.addNodes js/includes/sociogram.js /^sociogramClass.prototype.addNodes = function(){$/;" m +sociogramClass.arrange js/includes/sociogram.js /^sociogramClass.prototype.arrange = function(nodeId, pos, alone){$/;" m +sociogramClass.bindings js/includes/sociogram.js /^sociogramClass.prototype.bindings.clickNode = function(thisPtr, e){$/;" m +sociogramClass.bindings js/includes/sociogram.js /^sociogramClass.prototype.bindings.clickStage = function(thisPtr, e){$/;" m +sociogramClass.extractEdgesFromResponse js/includes/sociogram.js /^sociogramClass.prototype.extractEdgesFromResponse = function(){$/;" m +sociogramClass.extractNodesFromResponse js/includes/sociogram.js /^sociogramClass.prototype.extractNodesFromResponse = function(){$/;" m +sociogramClass.load js/includes/sociogram.js /^sociogramClass.prototype.load = function(){$/;" m +sociogramClass.nodeAt js/includes/sociogram.js /^sociogramClass.prototype.nodeAt = function(x, y){$/;" m +sociogramClass.overload js/includes/sociogram.js /^sociogramClass.prototype.overload.nodeDirectNeighbors = function(nodeId){$/;" m +sociogramClass.overload js/includes/sociogram.js /^sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){$/;" m +sociogramClass.overloadGraph js/includes/sociogram.js /^sociogramClass.prototype.overloadGraph = function(){$/;" m sortedCALL manager/module/call_log.php /^ $sortedCALL = array();$/;" v sortedMSMS manager/module/call_log.php /^ $sortedMSMS = array();$/;" v st config/dispatcher-tree.json /^ "st" : "\/src\/static",$/;" f diff --git a/view/charts.php b/view/charts.php index 9183c76..087df69 100755 --- a/view/charts.php +++ b/view/charts.php @@ -63,4 +63,4 @@ $render = $answer->get('render'); - \ No newline at end of file + diff --git a/view/js/charts.js b/view/js/charts.js index e939bd5..2819a70 100644 --- a/view/js/charts.js +++ b/view/js/charts.js @@ -1,410 +1,18 @@ /* [1] Gestion du sociogramme =========================================================*/ +var sociogram; +/* (1) On essaie de charger la classe du sociogramme */ +var alreadyLoaded = include('/js/includes/sociogram.js', null, true); +/* (2) Si il est pas déja chargé, on initialise le sociogramme */ +include('/js/includes/sociogram.js', function(){ + // On ajoute les méthodes si c'est la première fois qu'on charge + if( !alreadyLoaded ) sociogramClass.prototype.overloadGraph(); - -/* (0) On recupere les elements importants */ -var SOCIOGRAM = { - container: document.getElementById('sociogram'), - sigma: null, - - request: { path: 'charts/network_data' }, - response: null, - nodes: null, - edges: null, - rad: 500, - nodeDistance: 100, - arrange: null -}; - - - - - - -/* (0.5) Surcharge graph */ -// On recupere les voisins d'un noeud -sigma.classes.graph.addMethod('nodeNeighbors', function(nodeId){ - // On recupere les voisins du noeud courant - var neighbors = this.allNeighborsIndex[nodeId]; - - // Pile des voisins pour lesquels il faut chercher leurs voisins - var stack = []; - for( neighborId in neighbors ) stack.push(neighborId); - - // Tant qu'il reste des voisins a trouver - while( stack.length > 0 ){ - var subneighbors = this.allNeighborsIndex[stack[0]]; - for( subId in subneighbors ) - // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins - if( neighbors[subId] == null ){ - stack.push(subId); // On ajoute a la pile - neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete - } - - stack.shift(); - } - - - // On retourne le resultat - return neighbors; -}); - -// On recupere les voisins directs d'un noeud -sigma.classes.graph.addMethod('nodeDirectNeighbors', function(nodeId){ - // On retourne les voisins directs - return this.allNeighborsIndex[nodeId]; -}); - - - - - - - -/* (0.8) Initialisation de SIGMA */ -SOCIOGRAM.sigma = new sigma({renderer: { container: SOCIOGRAM.container, 'type': 'canvas' }}); - - - - - - - - - - -/* (1) On recupere les informations via l'API */ -api.send(SOCIOGRAM.request, function(response){ - console.log( response ); - // Si erreur, on quitte - if( response.ModuleError != 0 ) return; - - // Sinon on enregistre - SOCIOGRAM.response = response; - - - - - - - - /* (2) Parametrage de SIGMA */ - SOCIOGRAM.sigma.settings({ - defaultNodeColor: '#348ed8', - defaultLabelSize: 14, - defaultLabelBGColor: "#ddd", - defaultHoverLabelBGColor: "#002147", - defaultLabelHoverColor: "#fff", - labelThreshold: 10, - defaultEdgeType: "line" - }); - - - - - - - - /* (3) On recupere la liste des noeuds */ - SOCIOGRAM.nodes = []; - - // Pour chaque alter - for( var i = 0 ; i < SOCIOGRAM.response.data.alter.length ; i++ ){ - SOCIOGRAM.nodes.push({ - 'id': 'n-'+SOCIOGRAM.response.data.alter[i][0], - 'label': SOCIOGRAM.response.data.alter[i][1], - 'x': 0, - 'y': 0, - 'size': SOCIOGRAM.response.data.alter[i][2] - }); - } - - - - - - - - - /* (4) On recupere la liste des liens */ - SOCIOGRAM.edges = []; - - for( var i = 0 ; i < SOCIOGRAM.response.data.inter.length ; i++ ){ - SOCIOGRAM.edges.push({ - 'id': 'e-'+SOCIOGRAM.response.data.inter[i][0]+'-'+SOCIOGRAM.response.data.inter[i][1], - 'source': 'n-'+SOCIOGRAM.response.data.inter[i][0], - 'target': 'n-'+SOCIOGRAM.response.data.inter[i][1] - }); - } - - - - - - - - - /* (5) On ajoute nos noeuds */ - for( var i = 0 ; i < SOCIOGRAM.nodes.length ; i++) - SOCIOGRAM.sigma.graph.addNode(SOCIOGRAM.nodes[i]); - - - - - - - /* (6) On ajoute nos liens */ - for( var i = 0 ; i < SOCIOGRAM.edges.length ; i++) - SOCIOGRAM.sigma.graph.addEdge(SOCIOGRAM.edges[i]); - - - - - - - /* (7) Gestion des interactions */ - /* RETOURNE LA DISTANCE AVEC LE NOEUD LE PLUS PRES - * - * @x Abscisse du point - * @y Ordonnees du point - * - * @return distance Retourne la distance du noeud le plus proche - * - */ - SOCIOGRAM.nodeAt = function(x, y){ - var nodes = SOCIOGRAM.sigma.graph.nodes(); - var minDistance = null; - - for( nodeId in nodes ){ - var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); - if( minDistance == null || distance < minDistance ) - minDistance = distance; - } - - return minDistance; - }; - - - - /* POSITIONNE LES VOISINS AUTOUR DU NOEUD COURANT - * - * @nodeId Id du noeud courant - * @pos Contient {x, y} position initiale, sinon la position actuelle du noeud - * - */ - SOCIOGRAM.arrange = function(nodeId, pos, alone){ - var node = SOCIOGRAM.sigma.graph.nodes(nodeId); - - // Si le noeud est deja place, on ne fais rien - if( node.x != 0 || node.y != 0 ) return; - - var pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position - - // Tant que le noeud est trop proche d'un autre, on l'eloigne - // UNIQUEMENT si alone n'est pas NULL - if( alone ){ - while( SOCIOGRAM.nodeAt(pos.x, pos.y) < 2*SOCIOGRAM.nodeDistance ){ - pos = { - x: pos.x + 2*SOCIOGRAM.nodeDistance*Math.cos(Math.random()*2*Math.PI), - y: pos.y + 2*SOCIOGRAM.nodeDistance*Math.sin(Math.random()*2*Math.PI) - }; - } - } - - // On recupere les voisins directs - var neighborsId = SOCIOGRAM.sigma.graph.nodeDirectNeighbors(nodeId); - var neighbors = {}; - var neighborsCount = 0; - for( neighborId in neighborsId ){ - neighbors[neighborId] = SOCIOGRAM.sigma.graph.nodes(neighborId); - neighborsCount++; - } - - - // On positionne le noeud - node.x = pos.x; - node.y = pos.y; - - var angles = []; - - // On positionne chaque voisin si c'est pas deja fait - for( neighborId in neighbors ){ - var current = SOCIOGRAM.sigma.graph.nodes(neighborId); - // Si n'est pas deja positionne - if( current.x == 0 && current.y == 0 ){ - // On cherche un angle tant qu'il est pas trop pres d'un deja pris - var angle, alreadyUsed = false; - do{ - angle = Math.random()*2*Math.PI; - for( var i = 0 ; i < angles.length ; i++ ) - if( Math.abs(angle-angles[i]) > Math.PI/10 ){ - alreadyUsed = true; - break; - } - - }while( alreadyUsed ); - - current.x = pos.x + SOCIOGRAM.nodeDistance*Math.cos(angle); - current.y = pos.y + SOCIOGRAM.nodeDistance*Math.sin(angle); - SOCIOGRAM.arrange(current.id); - } - } - - SOCIOGRAM.sigma.refresh(); - }; - - // On affiche que les voisins d'un noeud - SOCIOGRAM.sigma.bind('clickNode', function(e){ - var nodeId = e.data.node.id; - // On recupere les voisins - var neighborNodes = SOCIOGRAM.sigma.graph.nodeNeighbors(nodeId); - neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique - - SOCIOGRAM.sigma.graph.nodes().forEach(function(n) { - if( neighborNodes[n.id] != null ) n.color = n.originalColor; - else n.color = '#eee'; - }); - - SOCIOGRAM.sigma.refresh(); - }); - - // On affiche tous les noeuds quand on clique dans le vide - SOCIOGRAM.sigma.bind('clickStage', function(e){ - SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ n.color = n.originalColor; }); - - SOCIOGRAM.sigma.refresh(); - }); - - - - - - - /* (8) On affiche le graphique */ - SOCIOGRAM.sigma.camera.ratio = 1.2; - - // On repartit les noeuds - SOCIOGRAM.sigma.refresh(); - SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ SOCIOGRAM.arrange(n.id, null, true); }); - - SOCIOGRAM.sigma.refresh(); + // On charge le graphique + sociogram = new sociogramClass(document.getElementById('sociogram')); + sociogram.load(); }); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -// var i, -// s, -// o, -// L = 10, -// N = 100, -// E = 500, -// g = { -// nodes: [], -// edges: [] -// }, -// step = 0; -// // Generate a random graph: -// for (i = 0; i < N; i++) { -// o = { -// id: 'n' + i, -// label: 'Node ' + i, -// circular_x: L * Math.cos(Math.PI * 2 * i / N - Math.PI / 2), -// circular_y: L * Math.sin(Math.PI * 2 * i / N - Math.PI / 2), -// circular_size: Math.random(), -// circular_color: '#' + ( -// Math.floor(Math.random() * 16777215).toString(16) + '000000' -// ).substr(0, 6), -// grid_x: i % L, -// grid_y: Math.floor(i / L), -// grid_size: 1, -// grid_color: '#ccc' -// }; -// ['x', 'y', 'size', 'color'].forEach(function(val) { -// o[val] = o['grid_' + val]; -// }); -// g.nodes.push(o); -// } -// for (i = 0; i < E; i++) -// g.edges.push({ -// id: 'e' + i, -// source: 'n' + (Math.random() * N | 0), -// target: 'n' + (Math.random() * N | 0), -// }); -// // Instantiate sigma: -// s = new sigma({ -// graph: g, -// renderer: { container: document.getElementById('graph-container'), 'type': 'canvas' }, -// settings: { -// animationsTime: 1000 -// } -// }); - -// setInterval(function(){ -// var prefix = ['grid_', 'circular_'][step = +!step]; -// sigma.plugins.animate( -// s, -// { -// x: prefix + 'x', -// y: prefix + 'y', -// size: prefix + 'size', -// color: prefix + 'color' -// } -// ); -// }, 10000); From e3e829d524c7f1939a4af9bf5ab3199ef0931ccf Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 15:05:42 +0200 Subject: [PATCH 02/21] =?UTF-8?q?Pr=C3=A9paration=20pour=20le=20refactor?= =?UTF-8?q?=20du=20call=5Flog=20(module)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- automate.php | 4 +- doc/sample.xml | 1001 ++++++++++++++++++++++++++++++++++++++++++++++++ tags | 2 +- view/input.php | 8 +- 4 files changed, 1008 insertions(+), 7 deletions(-) create mode 100644 doc/sample.xml diff --git a/automate.php b/automate.php index 0aa39d3..27880e4 100755 --- a/automate.php +++ b/automate.php @@ -21,7 +21,7 @@ /* [1] On recupere le journal d'appel =========================================================*/ - $file_content = file_get_contents('calllog.xml'); + $file_content = file_get_contents('doc/sample.xml'); var_dump( $file_content ); return; @@ -69,7 +69,7 @@ var_dump( $contact ); } - // parseCallLog(); + parseCallLog(); debug(); diff --git a/doc/sample.xml b/doc/sample.xml new file mode 100644 index 0000000..8757312 --- /dev/null +++ b/doc/sample.xml @@ -0,0 +1,1001 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tags b/tags index 9953437..0f6c410 100644 --- a/tags +++ b/tags @@ -2936,7 +2936,7 @@ fNOP phpunit/coverage/js/nv.d3.min.js /^(function(){var nv=window.nv||{};window. facebook manager/module/chart/networkChart.php /^ $facebook = 0x3b5998;$/;" v fetchData phpunit/tests/Database_delNumeric.php /^ $fetchData = array($/;" v fetchData phpunit/tests/Database_delNumeric.php /^ $fetchData = array(array($/;" v -file_content automate.php /^ $file_content = file_get_contents('calllog.xml');$/;" v +file_content automate.php /^ $file_content = file_get_contents('doc\/sample.xml');$/;" v file_content phpunit/tests/config.php /^ $file_content = file_get_contents( self::$config['database'] );$/;" v file_content phpunit/tests/config.php /^ $file_content = file_get_contents( self::$config['database-local'] );$/;" v file_content phpunit/tests/config.php /^ $file_content = file_get_contents( self::$config['dispatcher-extensions'] );$/;" v diff --git a/view/input.php b/view/input.php index 0e20124..d82d339 100755 --- a/view/input.php +++ b/view/input.php @@ -32,7 +32,7 @@ =========================================================*/ ?>
Saisie manuelle

- +
@@ -44,7 +44,7 @@
Liste des numeros les plus utilises.
-
+
Numero
Pseudo
Prenom
@@ -60,7 +60,8 @@
Expiré
- 0606060606 + 0606060606 +
Blabla Blabla Blabla @@ -84,4 +85,3 @@ ?>
Messenger
- From 1ba67b91757830b1b376794fcfc575e1829efedb Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 16:21:24 +0200 Subject: [PATCH 03/21] Parsage des journaux d'appels v2 --- automate.php | 36 +-- config/modules.json | 5 +- js/includes/sociogram.js | 514 +----------------------------------- manager/Database.php | 46 ++-- manager/module/call_log.php | 260 ++++++++++++------ tags | 34 ++- 6 files changed, 242 insertions(+), 653 deletions(-) diff --git a/automate.php b/automate.php index 27880e4..a39ec9b 100755 --- a/automate.php +++ b/automate.php @@ -10,7 +10,7 @@ use \api\client; - + debug(); /* PARSAGE DE JOURNAUX D'APPEL @@ -23,11 +23,12 @@ =========================================================*/ $file_content = file_get_contents('doc/sample.xml'); - var_dump( $file_content ); return; /* [2] On cree la requete =========================================================*/ - $request = new ModuleRequest('call_log/unserialize', array('filecontent'=>$file_content)); + $request = new ModuleRequest('call_log/unserialize', array( + 'file_content' => $file_content, + 'phone_number' => '01 02 03 04 05')); $answer = $request->dispatch(); // on l'execute /* [3] Si erreur @@ -42,36 +43,15 @@ /* [4] Sinon on recupere le resultat =========================================================*/ - $sms = $answer->get('sms'); - $call = $answer->get('call'); - $contact = $answer->get('contact'); + $directory = $answer->get('directory'); + $logs = $answer->get('logs'); - /* [5] On debug les donnees recues - =========================================================*/ - var_dump( "Il y a ".count($contact)." personnes :" ); - var_dump( "- ".count($sms)." par SMS/MMS" ); - var_dump( "- ".count($call)." par telephone" ); - echo "
"; - echo "TOP 10 DES APPELS
"; - echo "=================
"; - foreach($call as $v) - var_dump( $v[0] ." (".$contact[$v[0]].") \t\t\t". $v[1] ." appels"); - - echo "TOP 10 DES MMS/SMS
"; - echo "==================
"; - foreach($sms as $v) - var_dump( $v[0] ." (".$contact[$v[0]].") \t\t\t". $v[1] ." appels"); - - - var_dump("\n\n\nOBJET COMPLET"); - var_dump( $sms ); - var_dump( $call ); - var_dump( $contact ); + foreach($directory as $num=>$name) + echo $num.' <> '.$name.'
'; } parseCallLog(); - debug(); /* () Test du client de l'API generique */ diff --git a/config/modules.json b/config/modules.json index c341857..ec462e9 100755 --- a/config/modules.json +++ b/config/modules.json @@ -81,9 +81,10 @@ "call_log": { "unserialize": { "description": "Recupere le contenu d'un fichier XML de journal d'appel.", - "permissions": ["admin"], + "permissions": [], "parameters": { - "filecontent": { "description": "Contenu du fichier XML", "type": "text" } + "file_content": { "description": "Contenu du fichier XML", "type": "text" }, + "phone_number": { "description": "Numéro de téléphone de l'interrogé.", "type": "phone_number" } } } }, diff --git a/js/includes/sociogram.js b/js/includes/sociogram.js index 8aee70e..9739c08 100644 --- a/js/includes/sociogram.js +++ b/js/includes/sociogram.js @@ -22,8 +22,6 @@ function sociogramClass(container){ - - /* [2] Construction de la classe =========================================================*/ sociogramClass.prototype = { @@ -89,32 +87,6 @@ sociogramClass.prototype = { - - - - - - - - - - - - - - - - - - - - - - - - - - /* SURCHARGE DU GRAPH (@this.sigma.graph) -> Ajout de méthodes * */ @@ -122,25 +94,7 @@ sociogramClass.prototype.overloadGraph = function(){ sigma.classes.graph.addMethod('nodeNeighbors', this.overload.nodeNeighbors); sigma.classes.graph.addMethod('nodeDirectNeighbors', this.overload.nodeDirectNeighbors); this.log('graph overloaded'); -} - - - - - - - - - - - - - - - - - - +}; @@ -232,12 +186,6 @@ sociogramClass.prototype.load = function(){ - - - - - - @@ -274,12 +222,6 @@ sociogramClass.prototype.nodeAt = function(x, y){ - - - - - - /* POSITIONNE LES VOISINS AUTOUR DU NOEUD COURANT * * @nodeId Id du noeud courant @@ -308,12 +250,6 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ - - - - - - } } @@ -326,12 +262,6 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ - - - - - - var neighborsCount = 0; for( neighborId in neighborsId ){ neighbors[neighborId] = this.sigma.graph.nodes(neighborId); @@ -380,12 +310,6 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ - - - - - - /* RENVOIE LA LISTE DES VOISINS (DIRECTS & INDIRECTS) D'UN NOEUD DONNÉ * * @nodeId Id du noeud en question @@ -426,12 +350,6 @@ sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){ - - - - - - /* RENVOIE LA LISTE DES VOISINS DIRECTS D'UN NOEUD DONNÉ * * @nodeId Id du noeud en question @@ -451,12 +369,6 @@ sociogramClass.prototype.overload.nodeDirectNeighbors = function(nodeId){ - - - - - - /* EXTRAIT LES NOEUDS DE LA RÉPONSE DE L'API * */ @@ -483,12 +395,6 @@ sociogramClass.prototype.extractNodesFromResponse = function(){ - - - - - - /* EXTRAIT LES NOEUDS DE LA RÉPONSE DE L'API * */ @@ -512,12 +418,6 @@ sociogramClass.prototype.extractEdgesFromResponse = function(){ - - - - - - /* AJOUTE LES NOEUDS AU RENDU (SIGMA GRAPH) * */ @@ -534,12 +434,6 @@ sociogramClass.prototype.addNodes = function(){ - - - - - - /* AJOUTE LES LIENS AU RENDU (SIGMA GRAPH) * */ @@ -551,12 +445,6 @@ sociogramClass.prototype.addEdges = function(){ - - - - - - /* FONCTION ACTIVÉE LORS DU CLIC SUR UN NOEUD * */ @@ -578,12 +466,6 @@ sociogramClass.prototype.bindings.clickNode = function(thisPtr, e){ - - - - - - /* FONCTION ACTIVÉE LORS DU CLIC DANS LE VIDE * */ @@ -599,396 +481,6 @@ sociogramClass.prototype.bindings.clickStage = function(thisPtr, e){ - - - - - - - - - - - - - - - - - - - - - -// -// -// -// /* (0.5) Surcharge graph */ -// // On recupere les voisins d'un noeud -// if( typeof sigma.classes.graph.nodeNeighbors !== 'function ') -// sigma.classes.graph.addMethod('nodeNeighbors', function(nodeId){ -// // On recupere les voisins du noeud courant -// var neighbors = this.allNeighborsIndex[nodeId]; -// -// // Pile des voisins pour lesquels il faut chercher leurs voisins -// var stack = []; -// for( neighborId in neighbors ) stack.push(neighborId); -// -// // Tant qu'il reste des voisins a trouver -// while( stack.length > 0 ){ -// var subneighbors = this.allNeighborsIndex[stack[0]]; -// for( subId in subneighbors ) -// // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins -// if( neighbors[subId] == null ){ -// stack.push(subId); // On ajoute a la pile -// neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete -// } -// -// stack.shift(); -// } -// -// -// // On retourne le resultat -// return neighbors; -// }); -// -// // On recupere les voisins directs d'un noeud -// if( typeof sigma.classes.graph.nodeDirectNeighbors !== 'function ') -// sigma.classes.graph.addMethod('nodeDirectNeighbors', function(nodeId){ -// // On retourne les voisins directs -// return this.allNeighborsIndex[nodeId]; -// }); -// -// -// -// -// -// -// -// /* (0.8) Initialisation de SIGMA */ -// SOCIOGRAM.sigma = new sigma({renderer: { container: SOCIOGRAM.container, 'type': 'canvas' }}); -// -// -// -// -// -// -// -// -// -// -// /* (1) On recupere les informations via l'API */ -// api.send(SOCIOGRAM.request, function(response){ -// console.log( response ); -// // Si erreur, on quitte -// if( response.ModuleError != 0 ) return; -// -// // Sinon on enregistre -// SOCIOGRAM.response = response; -// -// -// -// -// -// -// -// /* (2) Parametrage de SIGMA */ -// SOCIOGRAM.sigma.settings({ -// defaultNodeColor: '#348ed8', -// defaultLabelSize: 14, -// defaultLabelBGColor: "#ddd", -// defaultHoverLabelBGColor: "#002147", -// defaultLabelHoverColor: "#fff", -// labelThreshold: 10, -// defaultEdgeType: "line" -// }); -// -// -// -// -// -// -// -// /* (3) On recupere la liste des noeuds */ -// SOCIOGRAM.nodes = []; -// -// // Pour chaque alter -// for( var i = 0 ; i < SOCIOGRAM.response.data.alter.length ; i++ ){ -// SOCIOGRAM.nodes.push({ -// 'id': 'n-'+SOCIOGRAM.response.data.alter[i][0], -// 'label': SOCIOGRAM.response.data.alter[i][1], -// 'x': 0, -// 'y': 0, -// 'size': SOCIOGRAM.response.data.alter[i][2] -// }); -// } -// -// -// -// -// -// -// -// -// /* (4) On recupere la liste des liens */ -// SOCIOGRAM.edges = []; -// -// for( var i = 0 ; i < SOCIOGRAM.response.data.inter.length ; i++ ){ -// SOCIOGRAM.edges.push({ -// 'id': 'e-'+SOCIOGRAM.response.data.inter[i][0]+'-'+SOCIOGRAM.response.data.inter[i][1], -// 'source': 'n-'+SOCIOGRAM.response.data.inter[i][0], -// 'target': 'n-'+SOCIOGRAM.response.data.inter[i][1] -// }); -// } -// -// -// -// -// -// -// -// -// /* (5) On ajoute nos noeuds */ -// for( var i = 0 ; i < SOCIOGRAM.nodes.length ; i++) -// SOCIOGRAM.sigma.graph.addNode(SOCIOGRAM.nodes[i]); -// -// -// -// -// -// -// /* (6) On ajoute nos liens */ -// for( var i = 0 ; i < SOCIOGRAM.edges.length ; i++) -// SOCIOGRAM.sigma.graph.addEdge(SOCIOGRAM.edges[i]); -// -// -// -// -// -// -// /* (7) Gestion des interactions */ -// /* RETOURNE LA DISTANCE AVEC LE NOEUD LE PLUS PRES -// * -// * @x Abscisse du point -// * @y Ordonnees du point -// * -// * @return distance Retourne la distance du noeud le plus proche -// * -// */ -// SOCIOGRAM.nodeAt = function(x, y){ -// var nodes = SOCIOGRAM.sigma.graph.nodes(); -// var minDistance = null; -// -// for( nodeId in nodes ){ -// var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); -// if( minDistance == null || distance < minDistance ) -// minDistance = distance; -// } -// -// return minDistance; -// }; - - - - - - - - - - - - -// -// -// -// /* POSITIONNE LES VOISINS AUTOUR DU NOEUD COURANT -// * -// * @nodeId Id du noeud courant -// * @pos Contient {x, y} position initiale, sinon la position actuelle du noeud -// * -// */ -// SOCIOGRAM.arrange = function(nodeId, pos, alone){ -// var node = SOCIOGRAM.sigma.graph.nodes(nodeId); -// -// // Si le noeud est deja place, on ne fais rien -// if( node.x != 0 || node.y != 0 ) return; -// -// var pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position -// -// // Tant que le noeud est trop proche d'un autre, on l'eloigne -// // UNIQUEMENT si alone n'est pas NULL -// if( alone ){ -// while( SOCIOGRAM.nodeAt(pos.x, pos.y) < 2*SOCIOGRAM.nodeDistance ){ -// pos = { -// x: pos.x + 2*SOCIOGRAM.nodeDistance*Math.cos(Math.random()*2*Math.PI), -// y: pos.y + 2*SOCIOGRAM.nodeDistance*Math.sin(Math.random()*2*Math.PI) -// }; - - - - - - - - - - - - -// } -// } -// -// // On recupere les voisins directs -// var neighborsId = SOCIOGRAM.sigma.graph.nodeDirectNeighbors(nodeId); -// var neighbors = {}; - - - - - - - - - - - - -// var neighborsCount = 0; -// for( neighborId in neighborsId ){ -// neighbors[neighborId] = SOCIOGRAM.sigma.graph.nodes(neighborId); -// neighborsCount++; -// } -// -// -// // On positionne le noeud -// node.x = pos.x; -// node.y = pos.y; -// -// var angles = []; -// -// // On positionne chaque voisin si c'est pas deja fait -// for( neighborId in neighbors ){ -// var current = SOCIOGRAM.sigma.graph.nodes(neighborId); -// // Si n'est pas deja positionne -// if( current.x == 0 && current.y == 0 ){ -// // On cherche un angle tant qu'il est pas trop pres d'un deja pris -// var angle, alreadyUsed = false; -// do{ -// angle = Math.random()*2*Math.PI; -// for( var i = 0 ; i < angles.length ; i++ ) -// if( Math.abs(angle-angles[i]) > Math.PI/10 ){ -// alreadyUsed = true; -// break; -// } -// -// }while( alreadyUsed ); -// -// current.x = pos.x + SOCIOGRAM.nodeDistance*Math.cos(angle); -// current.y = pos.y + SOCIOGRAM.nodeDistance*Math.sin(angle); -// SOCIOGRAM.arrange(current.id); -// } -// } -// -// SOCIOGRAM.sigma.refresh(); -// }; - - - - - - - - - - - - -// -// // On affiche que les voisins d'un noeud -// SOCIOGRAM.sigma.bind('clickNode', function(e){ -// var nodeId = e.data.node.id; -// // On recupere les voisins -// var neighborNodes = SOCIOGRAM.sigma.graph.nodeNeighbors(nodeId); -// neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique -// -// SOCIOGRAM.sigma.graph.nodes().forEach(function(n) { -// if( neighborNodes[n.id] != null ) n.color = n.originalColor; -// else n.color = '#eee'; -// }); -// -// SOCIOGRAM.sigma.refresh(); -// }); -// -// // On affiche tous les noeuds quand on clique dans le vide -// SOCIOGRAM.sigma.bind('clickStage', function(e){ -// SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ n.color = n.originalColor; }); -// -// SOCIOGRAM.sigma.refresh(); -// }); -// -// -// -// -// -// -// /* (8) On affiche le graphique */ -// SOCIOGRAM.sigma.camera.ratio = 1.2; -// -// // On repartit les noeuds -// SOCIOGRAM.sigma.refresh(); -// SOCIOGRAM.sigma.graph.nodes().forEach(function(n){ SOCIOGRAM.arrange(n.id, null, true); }); -// -// SOCIOGRAM.sigma.refresh(); -// -// }); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1033,10 +525,6 @@ sociogramClass.prototype.bindings.clickStage = function(thisPtr, e){ - - - - // ['x', 'y', 'size', 'color'].forEach(function(val) { // o[val] = o['grid_' + val]; // }); diff --git a/manager/Database.php b/manager/Database.php index df26985..7c63de4 100755 --- a/manager/Database.php +++ b/manager/Database.php @@ -1,10 +1,10 @@ 'f/json/database-local/conf', @@ -29,8 +29,8 @@ $this->dbname = $dbname; $this->username = $username; $this->password = $password; - - try{ + + try{ self::$pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password); // On signale que tout s'est bien passe @@ -57,7 +57,7 @@ self::$instance = new DataBase($conf['host'], $conf['dbname'], $conf['user'], $conf['password']); } - + return self::$instance; } @@ -104,7 +104,7 @@ * @fetchData le résultat d'une $requeteSQL->fetchAll() * @oneDimension FAUX <=> fetchAll ; VRAI <=> fetch * - * @return newFetchData retourne le tableau donné en paramètre mais sans les valeurs à clés numériques + * @return newFetchData retourne le tableau donné en paramètre mais sans les valeurs à clés numériques * */ public static function delNumeric($fetchData, $oneDimension=false){ @@ -121,19 +121,19 @@ // on supprime les doublons des entrées (indice numérique) for( $i = 0 ; $i < count($fetchData) ; $i++ ) // pour tout les utilisateurs foreach($fetchData[$i] as $col => $val){ // pour toutes les entrées - + if( !mb_detect_encoding($val, 'UTF-8') ) $fetchData[$i][$col] = utf8_encode($val); - + if( is_int($col) ){ // Si indice numerique if( $nextEquivalent ) // Si suit un indice textuel unset( $fetchData[$i][$col] ); // on supprime l'indice - + $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique }else // Si l'indice n'est pas un entier $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant - + } /* [2] 1 dimensions @@ -142,14 +142,14 @@ // on supprime les doublons des entrées (indice numérique) foreach($fetchData as $i=>$val){ // pour toutes les entrées - + if( !mb_detect_encoding($val, 'UTF-8') ) $fetchData[$i] = utf8_encode($val); if( is_int($i) ){ // Si indice numerique if( $nextEquivalent ) // Si suit un indice textuel unset( $fetchData[$i] ); // on supprime l'indice - + $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique }else // Si l'indice n'est pas un entier @@ -165,8 +165,8 @@ //////////////////////////////////////////////////////////////// - // _ __ _ _ _ - // __ _____ _ __(_)/ _(_) ___ __ _| |_(_) ___ _ __ ___ + // _ __ _ _ _ + // __ _____ _ __(_)/ _(_) ___ __ _| |_(_) ___ _ __ ___ // \ \ / / _ \ '__| | |_| |/ __/ _` | __| |/ _ \| '_ \/ __| // \ V / __/ | | | _| | (_| (_| | |_| | (_) | | | \__ \ // \_/ \___|_| |_|_| |_|\___\__,_|\__|_|\___/|_| |_|___/ @@ -223,9 +223,9 @@ return true; } - + /* [n] Sinon, tous les autres types definis - =========================================================*/ + =========================================================*/ switch($type){ // Entier positif (id dans BDD) case 'id': @@ -240,12 +240,18 @@ case 'mail': return $checker && is_string($value) && strlen($value) <= 50 && preg_match('/^[\w\.-]+@[\w\.-]+\.[a-z]{2,4}$/i', $value); break; - + // Hash sha1 case 'sha1': return $checker && is_string($value) && preg_match('/^[\da-f]{40}$/i', $value); break; - + break; + + // Numéro de téléphone + case 'phone_number': + return $checker && is_string($value) && preg_match('/^(?:0|\+33 ?|0?0?33 ?|)([1-9] ?(?:[0-9] ?){8})$/i', $value); + break; + default: return false; break; @@ -257,8 +263,8 @@ //////////////////////////////////// - // _ _ - // __| | __ _| |_ ___ ___ + // _ _ + // __| | __ _| |_ ___ ___ // / _` |/ _` | __/ _ \/ __| // | (_| | (_| | || __/\__ \ // \__,_|\__,_|\__\___||___/ diff --git a/manager/module/call_log.php b/manager/module/call_log.php index 5aad1d9..2f84b0b 100644 --- a/manager/module/call_log.php +++ b/manager/module/call_log.php @@ -9,6 +9,34 @@ class call_log{ + /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE + * + * @number Numéro de téléphone en +336/336/06 + * + * @return formatted Numéro formatté (06), on FALSE si erreur + * + */ + private static function formatNumber($number){ + // On met en quel que soit le type + $number = (string) $number; + + // On supprime tous les espaces + $number = str_replace(' ', '', $number); + + // On formatte le numéro + if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) + $number = '0'.$m[1]; + + // On retourne le numéro formatté + return $number; + } + + + + + + + /* DESERIALISATION D'UN JOURNAL D'APPEL * * @content Le contenu du journal d'appel a deserialiser @@ -19,93 +47,42 @@ * */ public static function unserialize($params){ - $content = null; + $file_content = null; extract($params); - /* [2] On recupere le xml + // On formatte le numéro de téléphone + $phone_number = self::formatNumber($phone_number); + + /* [1] On parse/récupère le xml =========================================================*/ - $xml = simplexml_load_string($content); + $xml = simplexml_load_string($file_content); // Si le format XML n'est pas bon, on retourne une erreur if( $xml === false ) return array('ModuleError' => ManagerError::ParsingFailed); - - /* [3] Initialisation des variables + /* [2] On lit chaque élément =========================================================*/ - $names = array(); // Contiendra les correspondances numero/contact - $msms = array(); // Contiendra les personnes utilisant SMS/MMS - $call = array(); // Contiendra les personnes utilisant CALL + $phone_directory = array(); // Contiendra les correspondances num->Nom + $phone_logs = array(); // Contiendra nos logs (appels/sms) - - /* [4] On traite les donnees pour chaque champ du xml - =========================================================*/ foreach($xml->Item as $log){ - // On recupere le numero en string - $num = (string) $log['Number']; + /* (1) On formatte le numéro */ + $number = self::formatNumber($log['Number']); - // On formatte le numero - if( preg_match("/^(?:\+33|33|0)(.+)/", $num, $m) ) - $num = '0'.$m[1]; - // Si pas un numero, on sort de la boucle - else - continue; + /* (2) On enregistre le contact dans l'annuaire s'il y est pas déjà */ + if( !isset($phone_directory[$number]) ) + $phone_directory[$number] = strlen($log['Name']) ? $log['Name'] : null; - - /* (1) Si le type est MMS ou SMS */ - if( $log['Type'] == 'SMS' || $log['Type'] == 'MMS' ){ - - // Si la personne n'est pas referencee, on l'ajoute - // Sinon on incremente son nombre d'apparition - if( isset($msms[$num]) ) - $msms[$num]+= 1; - else - $msms[$num] = 1; - - // On enregistre le nom si c'est pas fait - if( !isset($names[$num]) ) $names[$num] = $log['Name']; - - - /* (2) Si le type est PHONE */ - }else if( $log['Type'] == 'PHONE' ){ - - // Si la personne n'est pas referencee, on l'ajoute - // Sinon on incremente son nombre d'apparition - if( isset($call[$num]) ) - $call[$num]+= 1; - else - $call[$num] = 1; - - // On enregistre le nom si c'est pas fait - if( !isset($names[$num]) ) $names[$num] = $log['Name']; - - } - } - - - /* [4] On trie par nombre d'interactions (sms/appel) - =========================================================*/ - $tmp = $msms; - /* (1) Tri des SMS/MMS */ - $sortedMSMS = array(); - // On fait le tri pour les 10 premiers elements sauf s'il en a moins - for( $i = 0 ; $i < 10 && $i < count($tmp) ; $i++ ){ - $maxval = max($tmp); - $maxkey = array_search($maxval, $tmp); - array_push( $sortedMSMS, array($maxkey, $maxval) ); - unset($tmp[$maxkey]); - } - - - $tmp = $call; - /* (2) Tri des appels */ - $sortedCALL = array(); - // On fait le tri pour les 10 premiers elements sauf s'il en a moins - for( $i = 0 ; $i < 10 && $i < count($tmp) ; $i++ ){ - $maxval = max($tmp); - $maxkey = array_search($maxval, $tmp); - array_push( $sortedCALL, array($maxkey, $maxval) ); - unset($tmp[$maxkey]); + /* (3) On complète le log */ + $phone_log = array( + 'source' => ($log['Direction']=='INCOMING') ? $number : self::formatNumber($phone_number), + 'target' => ($log['Direction']=='INCOMING') ? self::formatNumber($phone_number) : $number, + 'type' => strtolower($log['Type']), + 'date' => strtotime($log['Date']), + 'duration' => (int) $log['Duration'] + ); + array_push($phone_logs, $phone_log); } @@ -113,15 +90,144 @@ =========================================================*/ return array( 'ModuleError' => ManagerError::Success, - 'sms' => $sortedMSMS, - 'call' => $sortedCALL, - 'contact' => $names + 'directory' => $phone_directory, + 'logs' => $phone_logs ); } + + + + + + + + + + + + + + + + /* DESERIALISATION D'UN JOURNAL D'APPEL + * + * @content Le contenu du journal d'appel a deserialiser + * + * @return sms Retourne un tableau associatif contenant les sms triees + * @return call Retourne un tableau associatif contenant les appels triees + * @return contact Retourne un tableau associatif contenant les correspondances numero/nom de contact + * + */ + private static function unserializeOld($params){ + $filecontent = null; + extract($params); + + /* [2] On recupere le xml + =========================================================*/ + $xml = simplexml_load_string($filecontent); + + // Si le format XML n'est pas bon, on retourne une erreur + if( $xml === false ) + return array('ModuleError' => ManagerError::ParsingFailed); + + return array( 'ModuleError' => ManagerError::Success, 'xml' => $xml ); + + + /* [3] Initialisation des variables + =========================================================*/ + $names = array(); // Contiendra les correspondances numero/contact + $msms = array(); // Contiendra les personnes utilisant SMS/MMS + $call = array(); // Contiendra les personnes utilisant CALL + + + /* [4] On traite les donnees pour chaque champ du xml + =========================================================*/ + foreach($xml->Item as $log){ + // On recupere le numero en string + $num = (string) $log['Number']; + + // On formatte le numero + if( preg_match("/^(?:\+33|33|0)(.+)/", $num, $m) ) + $num = '0'.$m[1]; + // Si pas un numero, on sort de la boucle + else + continue; + + + /* (1) Si le type est MMS ou SMS */ + if( $log['Type'] == 'SMS' || $log['Type'] == 'MMS' ){ + + // Si la personne n'est pas referencee, on l'ajoute + // Sinon on incremente son nombre d'apparition + if( isset($msms[$num]) ) + $msms[$num]+= 1; + else + $msms[$num] = 1; + + // On enregistre le nom si c'est pas fait + if( !isset($names[$num]) ) $names[$num] = $log['Name']; + + + /* (2) Si le type est PHONE */ + }else if( $log['Type'] == 'PHONE' ){ + + // Si la personne n'est pas referencee, on l'ajoute + // Sinon on incremente son nombre d'apparition + if( isset($call[$num]) ) + $call[$num]+= 1; + else + $call[$num] = 1; + + // On enregistre le nom si c'est pas fait + if( !isset($names[$num]) ) $names[$num] = $log['Name']; + + } + } + + + /* [4] On trie par nombre d'interactions (sms/appel) + =========================================================*/ + $tmp = $msms; + /* (1) Tri des SMS/MMS */ + $sortedMSMS = array(); + // On fait le tri pour les 10 premiers elements sauf s'il en a moins + for( $i = 0 ; $i < 10 && $i < count($tmp) ; $i++ ){ + $maxval = max($tmp); + $maxkey = array_search($maxval, $tmp); + array_push( $sortedMSMS, array($maxkey, $maxval) ); + unset($tmp[$maxkey]); + } + + + $tmp = $call; + /* (2) Tri des appels */ + $sortedCALL = array(); + // On fait le tri pour les 10 premiers elements sauf s'il en a moins + for( $i = 0 ; $i < 10 && $i < count($tmp) ; $i++ ){ + $maxval = max($tmp); + $maxkey = array_search($maxval, $tmp); + array_push( $sortedCALL, array($maxkey, $maxval) ); + unset($tmp[$maxkey]); + } + + + /* [5] Gestion du retour + =========================================================*/ + return array( + 'ModuleError' => ManagerError::Success, + 'sms' => $sortedMSMS, + 'call' => $sortedCALL, + 'contact' => $names + ); + } + + + + } diff --git a/tags b/tags index 0f6c410..e4157c5 100644 --- a/tags +++ b/tags @@ -2533,7 +2533,7 @@ buildPath manager/ResourceDispatcher.php /^ private function buildPath(){$/;" f c js/lib/sigma/plugins/sigma.exporters.svg.min.js /^(function(){"use strict";function a(a){return new Blob([a],{type:"image\/svg+xml;charset=utf-8"})}function b(b,c){var e=a(b),f={};f.anchor=document.createElement("a"),f.anchor.setAttribute("href",d.createObjectURL(e)),f.anchor.setAttribute("download",c);var g=document.createEvent("MouseEvent");g.initMouseEvent("click",!0,!1,window,0,0,0,0,0,!1,!1,!1,!1,0,null),d.revokeObjectURL(e),f.anchor.dispatchEvent(g),delete f.anchor}function c(a,b,c){var d,e,g,h,i,j={},k={},l=0,m="";c.classes&&(e=document.createElementNS(f,"style"),a.insertBefore(e,a.firstChild));var n=a.querySelectorAll('[id="'+b+'-group-nodes"] > [class="'+b+'-node"]');for(h=0,i=n.length,g=!0;i>h;h++)d=n[h].getAttribute("fill"),c.data||n[h].removeAttribute("data-node-id"),c.classes&&(d in j||(j[d]=g?b+"-node":"c-"+l++,m+="."+j[d]+"{fill: "+d+"}"),j[d]!==b+"-node"&&n[h].setAttribute("class",n[h].getAttribute("class")+" "+j[d]),n[h].removeAttribute("fill")),g=!1;var o=a.querySelectorAll('[id="'+b+'-group-edges"] > [class="'+b+'-edge"]');for(h=0,i=o.length,g=!0;i>h;h++)d=o[h].getAttribute("stroke"),c.data||o[h].removeAttribute("data-edge-id"),c.classes&&(d in k||(k[d]=g?b+"-edge":"c-"+l++,m+="."+k[d]+"{stroke: "+d+"}"),k[d]!==b+"-edge"&&o[h].setAttribute("class",o[h].getAttribute("class")+" "+k[d]),o[h].removeAttribute("stroke")),g=!1;c.classes&&e.appendChild(document.createTextNode(m))}if("undefined"==typeof sigma)throw"sigma.renderers.snapshot: sigma not in scope.";var d=this.URL||this.webkitURL||this,e={size:"1000",width:"1000",height:"1000",classes:!0,labels:!0,data:!1,download:!1,filename:"graph.svg"},f="http:\/\/www.w3.org\/2000\/svg";sigma.prototype.toSVG=function(a){a=a||{};var d=this.settings("classPrefix"),f=a.size||a.width||e.size,g=a.size||a.height||e.size,h=document.createElement("div");h.setAttribute("width",f),h.setAttribute("height",g),h.setAttribute("style","position:absolute; top: 0px; left:0px; width: "+f+"px; height: "+g+"px;");var i=this.addCamera(),j=this.addRenderer({camera:i,container:h,type:"svg",forceLabels:!!a.labels});j.resize(f,g),this.refresh(),this.killRenderer(j),this.killCamera(i);var k=h.querySelector("svg");if(k.removeAttribute("style"),k.setAttribute("width",f+"px"),k.setAttribute("height",g+"px"),k.setAttribute("x","0px"),k.setAttribute("y","0px"),!a.labels){var l=k.querySelector('[id="'+d+'-group-labels"]');k.removeChild(l)}var m=k.querySelector('[id="'+d+'-group-hovers"]');k.removeChild(m),a.classes=a.classes!==!1,(!a.data||a.classes)&&c(k,d,a);var n=k.outerHTML;h=null;var o='\\n';return o+='\\n',o+=n,a.download&&b(o,a.filename||e.filename),o}}).call(this);/;" f c js/lib/sigma/plugins/sigma.parsers.gexf.min.js /^(function(a){"use strict";function b(a){var b={id:a.id,label:a.label};return a.viz&&(b.viz=a.viz),a.attributes&&(b.attributes=a.attributes),b}function c(a){var b={id:a.id,type:a.type||"undirected",label:a.label||"",source:a.source,target:a.target,weight:+a.weight||1};return a.viz&&(b.viz=a.viz),a.attributes&&(b.attributes=a.attributes),b}function d(a){function d(){var a={};return l.els.meta?(a.lastmodifieddate=l.els.meta.getAttribute("lastmodifieddate"),h.nodeListEach(l.els.meta.childNodes,function(b){a[b.tagName.toLowerCase()]=b.textContent}),a):a}function e(a){var b=[];return l.els.model[a]&&h.nodeListEach(l.els.model[a],function(a){var c={id:a.getAttribute("id")||a.getAttribute("for"),type:a.getAttribute("type")||"string",title:a.getAttribute("title")||""},d=h.nodeListToArray(a.childNodes);d.length>0&&(c.defaultValue=d[0].textContent),b.push(c)}),b.length>0?b:!1}function f(a,b){var c={},d=b.getElementsByTagName("attvalue"),e=h.nodeListToHash(d,function(a){var b=h.namedNodeMapToObject(a.attributes),c=b.id||b["for"];return{key:c,value:b.value}});return a.map(function(a){c[a.id]=!(a.id in e)&&"defaultValue"in a?h.enforceType(a.type,a.defaultValue):h.enforceType(a.type,e[a.id])}),c}function g(a){var c=[];return h.nodeListEach(l.els.nodes,function(d){var e={id:d.getAttribute("id"),label:d.getAttribute("label")||""};a&&(e.attributes=f(a,d)),l.hasViz&&(e.viz=i(d)),c.push(b(e))}),c}function i(a){var b={},c=h.getFirstElementByTagNS(a,"viz","color");if(c){var d=["r","g","b","a"].map(function(a){return c.getAttribute(a)});b.color=h.getRGB(d)}var e=h.getFirstElementByTagNS(a,"viz","position");e&&(b.position={},["x","y","z"].map(function(a){b.position[a]=+e.getAttribute(a)}));var f=h.getFirstElementByTagNS(a,"viz","size");f&&(b.size=+f.getAttribute("value"));var g=h.getFirstElementByTagNS(a,"viz","shape");return g&&(b.shape=g.getAttribute("value")),b}function j(a,b){var d=[];return h.nodeListEach(l.els.edges,function(e){var g=h.namedNodeMapToObject(e.attributes);"type"in g||(g.type=b),a&&(g.attributes=f(a,e)),l.hasViz&&(g.viz=k(e)),d.push(c(g))}),d}function k(a){var b={},c=h.getFirstElementByTagNS(a,"viz","color");if(c){var d=["r","g","b","a"].map(function(a){return c.getAttribute(a)});b.color=h.getRGB(d)}var e=h.getFirstElementByTagNS(a,"viz","shape");e&&(b.shape=e.getAttribute("value"));var f=h.getFirstElementByTagNS(a,"viz","thickness");return f&&(b.thickness=+f.getAttribute("value")),b}var l={};l.els={root:a.getElementsByTagName("gexf")[0],graph:a.getElementsByTagName("graph")[0],meta:a.getElementsByTagName("meta")[0],nodes:a.getElementsByTagName("node"),edges:a.getElementsByTagName("edge"),model:h.getModelTags(a)},l.hasViz=!!h.getAttributeNS(l.els.root,"xmlns","viz"),l.version=l.els.root.getAttribute("version")||"1.0",l.mode=l.els.graph.getAttribute("mode")||"static";var m=l.els.graph.getAttribute("defaultedgetype");l.defaultEdgetype=m||"undirected";var n=e("node"),o=e("edge"),p={version:l.version,mode:l.mode,defaultEdgeType:l.defaultEdgetype,meta:d(),model:{},nodes:g(n),edges:j(o,l.defaultEdgetype)};return n&&(p.model.node=n),o&&(p.model.edge=o),p}function e(a,b){var c=function(){if(window.XMLHttpRequest)return new XMLHttpRequest;var a,b;if(window.ActiveXObject){a=["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];for(b in a)try{return new ActiveXObject(a[b])}catch(c){}}return null}();if(!c)throw"XMLHttpRequest not supported, cannot load the file.";var d,e="function"==typeof b;return c.overrideMimeType?(c.overrideMimeType("text\/xml"),d=function(a){return a.responseXML}):d=function(a){var b=new DOMParser;return b.parseFromString(a.responseText,"application\/xml")},c.open("GET",a,e),e&&(c.onreadystatechange=function(){4===c.readyState&&b(d(c))}),c.send(),e?c:d(c)}function f(a){return d(a)}function g(a,b){return"function"==typeof b?e(a,function(a){b(d(a))}):d(e(a))}var h={getModelTags:function(a){var b,c=a.getElementsByTagName("attributes"),d={},e=c.length;for(b=0;e>b;b++)d[c[b].getAttribute("class")]=c[b].childNodes;return d},nodeListToArray:function(a){for(var b=[],c=0,d=a.length;d>c;++c)"#text"!==a[c].nodeName&&b.push(a[c]);return b},nodeListEach:function(a,b){for(var c=0,d=a.length;d>c;++c)"#text"!==a[c].nodeName&&b(a[c])},nodeListToHash:function(a,b){for(var c={},d=0;df;f++)i=h[f],i.id=i.id,i.viz&&"object"==typeof i.viz&&(i.viz.position&&"object"==typeof i.viz.position&&(i.x=i.viz.position.x,i.y=-i.viz.position.y),i.size=i.viz.size,i.color=i.viz.color);for(h=b.edges,f=0,g=h.length;g>f;f++)i=h[f],i.id="string"==typeof i.id?i.id:a(),i.source=""+i.source,i.target=""+i.target,i.viz&&"object"==typeof i.viz&&(i.color=i.viz.color,i.size=i.viz.thickness),i.size=i.weight,i.direction=i.type,delete i.type;if(c instanceof sigma){for(c.graph.clear(),h=b.nodes,f=0,g=h.length;g>f;f++)c.graph.addNode(h[f]);for(h=b.edges,f=0,g=h.length;g>f;f++)c.graph.addEdge(h[f])}else"object"==typeof c?(c.graph=b,c=new sigma(c)):"function"==typeof c&&(d=c,c=null);return d?void d(c||b):b}var f,g,h,i;if("string"==typeof b)gexf.fetch(b,e);else if("object"==typeof b)return e(gexf.parse(b))}}.call(this);/;" f call automate.php /^ $call = $answer->get('call');$/;" v -call manager/module/call_log.php /^ $call = array(); \/\/ Contiendra les personnes utilisant CALL$/;" v +call manager/module/call_log.php /^ $call = array(); \/\/ Contiendra les personnes utilisant CALL$/;" v call router/Route.php /^ public function call(){$/;" f call_log config/modules.json /^ "call_log": {$/;" f call_log manager/module/call_log.php /^ class call_log{$/;" c @@ -2628,7 +2628,6 @@ console.dir js/lib/highcharts/js/modules/canvas-tools.js /^if(!window.console)wi console.log js/lib/highcharts/js/modules/canvas-tools.js /^if(!window.console)window.console={},window.console.log=function(){},window.console.dir=function(){};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(m){for(var a=0;aget('contact');$/;" v content manager/ResourceDispatcher.php /^ $content = file_get_contents($this->path);$/;" v -content manager/module/call_log.php /^ $content = null;$/;" v correct manager/ResourceDispatcher.php /^ $correct = $correct && preg_match('\/^[\\w_-]+$\/i', $serialFlags[3]);$/;" v correct manager/ResourceDispatcher.php /^ $correct = $correct && array_key_exists($serialFlags[0], self::$supported_extensions);$/;" v correct manager/ResourceDispatcher.php /^ $correct = $correct && array_key_exists($serialFlags[2], self::$supported_parents);$/;" v @@ -2946,6 +2945,8 @@ file_content phpunit/tests/config.php /^ $file_content = file_get_contents( se file_content phpunit/tests/config.php /^ $file_content = file_get_contents( self::$config['repositories'] );$/;" v file_content phpunit/tests/config.php /^ $file_content = file_get_contents( self::$config['views'] );$/;" v filecontent config/modules.json /^ "filecontent": { "description": "Contenu du fichier XML", "type": "text" }$/;" f +filecontent manager/module/call_log.php /^ $filecontent = null;$/;" v +filecontent manager/module/call_log.php /^ $filecontent = null;$/;" v fillParameters api/client.php /^ private function fillParameters($before, $parameters){$/;" f fillWithType js/lib/highcharts/api/js/ref.js /^ function fillWithType(type) {$/;" f fireEvent js/lib/highcharts/js/highcharts.src.js /^ };$/;" f @@ -2959,6 +2960,7 @@ flags manager/ResourceDispatcher.php /^ private $flags;$/;" v fn js/lib/sigma/sigma.js /^ o.easing;$/;" f fn js/lib/sigma/sigma.require.js /^ o.easing;$/;" f formatChecker js/lib/input-checker.js /^function formatChecker(pValue, pPattern, pRules){$/;" c +formatNumber manager/module/call_log.php /^ private static function formatNumber($number){$/;" f frDate manager/Database.php /^ public static function frDate($date){$/;" f fromPost manager/ModuleRequest.php /^ public static function fromPost($post){$/;" f fromString manager/ModuleRequest.php /^ public static function fromString($jsonString){$/;" f @@ -3249,8 +3251,8 @@ matches router/Route.php /^ $this->matches = $matches;$/;" v matches router/Route.php /^ private $matches = array();$/;" v max manager/Database.php /^ $max = (int) $match[2];$/;" v max phpunit/tests/Database_check.php /^ $max = rand(1, 255);$/;" v -maxkey manager/module/call_log.php /^ $maxkey = array_search($maxval, $tmp);$/;" v -maxval manager/module/call_log.php /^ $maxval = max($tmp);$/;" v +maxkey manager/module/call_log.php /^ $maxkey = array_search($maxval, $tmp);$/;" v +maxval manager/module/call_log.php /^ $maxval = max($tmp);$/;" v menu manager/MenuManager.php /^ $menu = array();$/;" v menuInflater view.php /^ $menuInflater = new MenuManager();$/;" v method api/manifest.default.json /^ "method": "@request_http_method",$/;" f @@ -3273,13 +3275,13 @@ months manager/Database.php /^ $months = array("Janvier", "Février", "Mars", mousedowned.ended phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f mousedowned.moved phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f moved.ended phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f -msms manager/module/call_log.php /^ $msms = array(); \/\/ Contiendra les personnes utilisant SMS\/MMS$/;" v +msms manager/module/call_log.php /^ $msms = array(); \/\/ Contiendra les personnes utilisant SMS\/MMS$/;" v name api/client.php /^ $name = $manifest['name'];$/;" v name api/client.php /^ private $name;$/;" v name api/manifest.default.json /^ "name": "@api_name",$/;" f name api/manifest.json /^ "name": "socioview_api",$/;" f name config/modules.json /^ "name" : { "description": "Nom attribue au token", "type": "varchar(3,50)" },$/;" f -names manager/module/call_log.php /^ $names = array(); \/\/ Contiendra les correspondances numero\/contact$/;" v +names manager/module/call_log.php /^ $names = array(); \/\/ Contiendra les correspondances numero\/contact$/;" v navMenu js/action-script.js /^function navMenu(section){$/;" f navSubMenu js/action-script.js /^function navSubMenu(subsection){$/;" f nb_circles manager/module/chart/networkChart.php /^ $nb_circles = 4;$/;" v @@ -3311,8 +3313,10 @@ nextEquivalent manager/Database.php /^ $nextEquivalent = false; \/\/ Vaut VRAI nodesBy js/lib/sigma/plugins/sigma.plugins.filter.min.js /^(function(undefined){"use strict";function register(a,b,c){if(c!=undefined&&"string"!=typeof c)throw'The filter key "'+c.toString()+'" must be a string.';if(c!=undefined&&!c.length)throw"The filter key must be a non-empty string.";if("function"!=typeof a)throw'The predicate of key "'+c+'" must be a function.';if("undo"===c)throw'"undo" is a reserved key.';if(_keysIndex[c])throw'The filter "'+c+'" already exists.';c&&(_keysIndex[c]=!0),_chain.push({key:c,processor:a,predicate:b})}function unregister(a){_chain=_chain.filter(function(b){return!(b.key in a)});for(var b in a)delete _keysIndex[b]}function Filter(a){_s=a,_g=a.graph}function deepCopy(o){var copy=Object.create(null);for(var i in o)"object"==typeof o[i]&&null!==o[i]?copy[i]=deepCopy(o[i]):"function"==typeof o[i]&&null!==o[i]?eval(" copy[i] = "+o[i].toString()):copy[i]=o[i];return copy}function cloneChain(a){for(var b=a.slice(0),c=0,d=b.length;d>c;c++)b[c]=deepCopy(b[c]),"function"==typeof b[c].processor&&(b[c].processor="filter.processors."+b[c].processor.name);return b}if("undefined"==typeof sigma)throw"sigma is not declared";sigma.utils.pkg("sigma.plugins"),sigma.classes.graph.hasMethod("adjacentNodes")||sigma.classes.graph.addMethod("adjacentNodes",function(a){if("string"!=typeof a)throw"adjacentNodes: the node id must be a string.";var b,c=[];for(b in this.allNeighborsIndex[a])c.push(this.nodesIndex[b]);return c}),sigma.classes.graph.hasMethod("adjacentEdges")||sigma.classes.graph.addMethod("adjacentEdges",function(a){if("string"!=typeof a)throw"adjacentEdges: the node id must be a string.";var b,c,d=this.allNeighborsIndex[a],e=[];for(c in d)for(b in d[c])e.push(d[c][b]);return e});var _g=undefined,_s=undefined,_chain=[],_keysIndex=Object.create(null),Processors={};Processors.nodes=function(a){for(var b=_g.nodes(),c=b.length,d=_g.edges(),e=d.length;c--;)b[c].hidden=!a.call(_g,b[c])||b[c].hidden;for(;e--;)(_g.nodes(d[e].source).hidden||_g.nodes(d[e].target).hidden)&&(d[e].hidden=!0)},Processors.edges=function(a){for(var b=_g.edges(),c=b.length;c--;)b[c].hidden=!a.call(_g,b[c])||b[c].hidden},Processors.neighbors=function a(b){for(var c=_g.nodes(),d=c.length,e=_g.edges(),f=e.length,a=_g.adjacentNodes(b),g=a.length,h={};g--;)h[a[g].id]=!0;for(;d--;)c[d].id===b||c[d].id in h||(c[d].hidden=!0);for(;f--;)(_g.nodes(e[f].source).hidden||_g.nodes(e[f].target).hidden)&&(e[f].hidden=!0)},Filter.prototype.nodesBy=function(a,b){return register(Processors.nodes,a,b),this},Filter.prototype.edgesBy=function(a,b){return register(Processors.edges,a,b),this},Filter.prototype.neighborsOf=function(a,b){if("string"!=typeof a)throw'The node id "'+a.toString()+'" must be a string.';if(!a.length)throw"The node id must be a non-empty string.";return register(Processors.neighbors,a,b),this},Filter.prototype.apply=function(){for(var a=0,b=_chain.length;b>a;++a)_chain[a].processor(_chain[a].predicate);return _chain[0]&&"undo"===_chain[0].key&&_chain.shift(),_s.refresh(),this},Filter.prototype.undo=function(a){function b(){for(var a=_g.nodes(),b=a.length,c=_g.edges(),d=c.length;b--;)a[b].hidden=!1;for(;d--;)c[d].hidden=!1}var c=Object.create(null),d=arguments.length;if(1===d)if("[object Array]"===Object.prototype.toString.call(a))for(var e=0,f=a.length;f>e;e++)c[a[e]]=!0;else c[a]=!0;else if(d>1)for(var e=0;d>e;e++)c[arguments[e]]=!0;else this.clear();return unregister(c),_chain.unshift({key:"undo",processor:b}),this},Filter.prototype.clear=function(){return _chain.length=0,_keysIndex=Object.create(null),this},Filter.prototype.export=function(){var a=cloneChain(_chain);return a},Filter.prototype.import=function(a){if(a===undefined)throw"Wrong arguments.";if("[object Array]"!==Object.prototype.toString.call(a))throw'The chain" must be an array.';for(var b=cloneChain(a),c=0,d=b.length;d>c;c++){if(b[c].predicate===undefined||b[c].processor===undefined)throw"Wrong arguments.";if(b[c].key!=undefined&&"string"!=typeof b[c].key)throw'The filter key "'+b[c].key.toString()+'" must be a string.';if("function"!=typeof b[c].predicate)throw'The predicate of key "'+b[c].key+'" must be a function.';if("string"!=typeof b[c].processor)throw'The processor of key "'+b[c].key+'" must be a string.';switch(b[c].processor){case"filter.processors.nodes":b[c].processor=Processors.nodes;break;case"filter.processors.edges":b[c].processor=Processors.edges;break;case"filter.processors.neighbors":b[c].processor=Processors.neighbors;break;default:throw"Unknown processor "+b[c].processor}}return _chain=b,this};var filter=null;sigma.plugins.filter=function(a){return filter||(filter=new Filter(a)),filter}}).call(this);/;" m noop js/lib/highcharts/js/modules/drilldown.src.js /^ var noop = function () {},$/;" f now phpunit/coverage/js/holder.min.js /^(function(window){if(!window.document)return;var document=window.document;if(!document.querySelectorAll){document.querySelectorAll=function(selectors){var style=document.createElement("style"),elements=[],element;document.documentElement.firstChild.appendChild(style);document._qsa=[];style.styleSheet.cssText=selectors+"{x-qsa:expression(document._qsa && document._qsa.push(this))}";window.scrollBy(0,0);style.parentNode.removeChild(style);while(document._qsa.length){element=document._qsa.shift();element.style.removeAttribute("x-qsa");elements.push(element)}document._qsa=null;return elements}}if(!document.querySelector){document.querySelector=function(selectors){var elements=document.querySelectorAll(selectors);return elements.length?elements[0]:null}}if(!document.getElementsByClassName){document.getElementsByClassName=function(classNames){classNames=String(classNames).replace(\/^|\\s+\/g,".");return document.querySelectorAll(classNames)}}if(!Object.keys){Object.keys=function(o){if(o!==Object(o)){throw TypeError("Object.keys called on non-object")}var ret=[],p;for(p in o){if(Object.prototype.hasOwnProperty.call(o,p)){ret.push(p)}}return ret}}(function(global){var B64_ALPHABET="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=";global.atob=global.atob||function(input){input=String(input);var position=0,output=[],buffer=0,bits=0,n;input=input.replace(\/\\s\/g,"");if(input.length%4===0){input=input.replace(\/=+$\/,"")}if(input.length%4===1){throw Error("InvalidCharacterError")}if(\/[^+\/0-9A-Za-z]\/.test(input)){throw Error("InvalidCharacterError")}while(position>16&255));output.push(String.fromCharCode(buffer>>8&255));output.push(String.fromCharCode(buffer&255));bits=0;buffer=0}position+=1}if(bits===12){buffer=buffer>>4;output.push(String.fromCharCode(buffer&255))}else if(bits===18){buffer=buffer>>2;output.push(String.fromCharCode(buffer>>8&255));output.push(String.fromCharCode(buffer&255))}return output.join("")};global.btoa=global.btoa||function(input){input=String(input);var position=0,out=[],o1,o2,o3,e1,e2,e3,e4;if(\/[^\\x00-\\xFF]\/.test(input)){throw Error("InvalidCharacterError")}while(position>2;e2=(o1&3)<<4|o2>>4;e3=(o2&15)<<2|o3>>6;e4=o3&63;if(position===input.length+2){e3=64;e4=64}else if(position===input.length+1){e4=64}out.push(B64_ALPHABET.charAt(e1),B64_ALPHABET.charAt(e2),B64_ALPHABET.charAt(e3),B64_ALPHABET.charAt(e4))}return out.join("")}})(window);if(!Object.prototype.hasOwnProperty){Object.prototype.hasOwnProperty=function(prop){var proto=this.__proto__||this.constructor.prototype;return prop in this&&(!(prop in proto)||proto[prop]!==this[prop])}}(function(){if("performance"in window===false){window.performance={}}Date.now=Date.now||function(){return(new Date).getTime()};if("now"in window.performance===false){var nowOffset=Date.now();if(performance.timing&&performance.timing.navigationStart){nowOffset=performance.timing.navigationStart}window.performance.now=function now(){return Date.now()-nowOffset}}})();if(!window.requestAnimationFrame){if(window.webkitRequestAnimationFrame){(function(global){global.requestAnimationFrame=function(callback){return webkitRequestAnimationFrame(function(){callback(global.performance.now())})};global.cancelAnimationFrame=webkitCancelAnimationFrame})(window)}else if(window.mozRequestAnimationFrame){(function(global){global.requestAnimationFrame=function(callback){return mozRequestAnimationFrame(function(){callback(global.performance.now())})};global.cancelAnimationFrame=mozCancelAnimationFrame})(window)}else{(function(global){global.requestAnimationFrame=function(callback){return global.setTimeout(callback,1e3\/60)};global.cancelAnimationFrame=global.clearTimeout})(window)}}})(this);(function webpackUniversalModuleDefinition(root,factory){if(typeof exports==="object"&&typeof module==="object")module.exports=factory();else if(typeof define==="function"&&define.amd)define(factory);else if(typeof exports==="object")exports["Holder"]=factory();else root["Holder"]=factory()})(this,function(){return function(modules){var installedModules={};function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={exports:{},id:moduleId,loaded:false};modules[moduleId].call(module.exports,module,module.exports,__webpack_require__);module.loaded=true;return module.exports}__webpack_require__.m=modules;__webpack_require__.c=installedModules;__webpack_require__.p="";return __webpack_require__(0)}([function(module,exports,__webpack_require__){(function(global){var onDomReady=__webpack_require__(1);var SceneGraph=__webpack_require__(2);var utils=__webpack_require__(3);var querystring=__webpack_require__(4);var extend=utils.extend;var getNodeArray=utils.getNodeArray;var dimensionCheck=utils.dimensionCheck;var SVG_NS="http:\/\/www.w3.org\/2000\/svg";var NODE_TYPE_COMMENT=8;var version="2.7.1";var generatorComment="\\n"+"Created with Holder.js "+version+".\\n"+"Learn more at http:\/\/holderjs.com\\n"+"(c) 2012-2015 Ivan Malopinsky - http:\/\/imsky.co\\n";var Holder={version:version,addTheme:function(name,theme){name!=null&&theme!=null&&(App.settings.themes[name]=theme);delete App.vars.cache.themeKeys;return this},addImage:function(src,el){var node=document.querySelectorAll(el);if(node.length){for(var i=0,l=node.length;i1){var offsetX=0;var offsetY=0;var lineIndex=0;var lineKey;line=new Shape.Group("line"+lineIndex);if(scene.align==="left"||scene.align==="right"){maxLineWidth=scene.width*(1-(1-App.setup.lineWrapRatio)*2)}for(var i=0;i=maxLineWidth||newline===true)){finalizeLine(holderTextGroup,line,offsetX,holderTextGroup.properties.leading);holderTextGroup.add(line);offsetX=0;offsetY+=holderTextGroup.properties.leading;lineIndex+=1;line=new Shape.Group("line"+lineIndex);line.y=offsetY}if(newline===true){continue}textNode.moveTo(offsetX,0);offsetX+=tpdata.spaceWidth+word.width;line.add(textNode)}finalizeLine(holderTextGroup,line,offsetX,holderTextGroup.properties.leading);holderTextGroup.add(line);if(scene.align==="left"){holderTextGroup.moveTo(scene.width-sceneMargin,null,null)}else if(scene.align==="right"){for(lineKey in holderTextGroup.children){line=holderTextGroup.children[lineKey];line.moveTo(scene.width-line.width,null,null)}holderTextGroup.moveTo(0-(scene.width-sceneMargin),null,null)}else{for(lineKey in holderTextGroup.children){line=holderTextGroup.children[lineKey];line.moveTo((holderTextGroup.width-line.width)\/2,null,null)}holderTextGroup.moveTo((scene.width-holderTextGroup.width)\/2,null,null)}holderTextGroup.moveTo(null,(scene.height-holderTextGroup.height)\/2,null);if((scene.height-holderTextGroup.height)\/2<0){holderTextGroup.moveTo(null,0,null)}}else{textNode=new Shape.Text(scene.text);line=new Shape.Group("line0");line.add(textNode);holderTextGroup.add(line);if(scene.align==="left"){holderTextGroup.moveTo(scene.width-sceneMargin,null,null)}else if(scene.align==="right"){holderTextGroup.moveTo(0-(scene.width-sceneMargin),null,null)}else{holderTextGroup.moveTo((scene.width-tpdata.boundingBox.width)\/2,null,null)}holderTextGroup.moveTo(null,(scene.height-tpdata.boundingBox.height)\/2,null)}return sceneGraph}function textSize(width,height,fontSize){var stageWidth=parseInt(width,10);var stageHeight=parseInt(height,10);var bigSide=Math.max(stageWidth,stageHeight);var smallSide=Math.min(stageWidth,stageHeight);var newHeight=.8*Math.min(smallSide,bigSide*App.defaults.scale);return Math.round(Math.max(fontSize,newHeight))}function updateResizableElements(element){var images;if(element==null||element.nodeType==null){images=App.vars.resizableImages}else{images=[element]}for(var i=0,l=images.length;i1){stagingTextNode.nodeValue="";for(var i=0;i=0;i--){var csspi=xml.createProcessingInstruction("xml-stylesheet",'href="'+stylesheets[i]+'" rel="stylesheet"');xml.insertBefore(csspi,xml.firstChild)}xml.removeChild(xml.documentElement);svgCSS=serializer.serializeToString(xml)}var svgText=serializer.serializeToString(svg);svgText=svgText.replace(\/\\&(\\#[0-9]{2,}\\;)\/g,"&$1");return svgCSS+svgText}function createXML(){if(!global.DOMParser)return;return(new DOMParser).parseFromString("","application\/xml")}function debounce(fn){if(!App.vars.debounceTimer)fn.call(this);if(App.vars.debounceTimer)global.clearTimeout(App.vars.debounceTimer);$/;" f -num manager/module/call_log.php /^ $num = '0'.$m[1];$/;" v -num manager/module/call_log.php /^ $num = (string) $log['Number'];$/;" v +num manager/module/call_log.php /^ $num = '0'.$m[1];$/;" v +num manager/module/call_log.php /^ $num = (string) $log['Number'];$/;" v +number manager/module/call_log.php /^ $number = '0'.$m[1];$/;" v +number manager/module/call_log.php /^ $number = (string) $number;$/;" v nv phpunit/coverage/js/nv.d3.min.js /^chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},focusHeight:{get:function(){return height2},set:function(_){height2=_}},showLegend:{get:function(){return showLegend},set:function(_){showLegend=_}},brushExtent:{get:function(){return brushExtent},set:function(_){brushExtent=_}},tooltips:{get:function(){return tooltips},set:function(_){tooltips=_}},tooltipContent:{get:function(){return tooltip},set:function(_){tooltip=_}},defaultState:{get:function(){return defaultState},set:function(_){defaultState=_}},noData:{get:function(){return noData},set:function(_){noData=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_);legend.color(color)}},interpolate:{get:function(){return lines.interpolate()},set:function(_){lines.interpolate(_);lines2.interpolate(_)}},xTickFormat:{get:function(){return xAxis.xTickFormat()},set:function(_){xAxis.xTickFormat(_);x2Axis.xTickFormat(_)}},yTickFormat:{get:function(){return yAxis.yTickFormat()},set:function(_){yAxis.yTickFormat(_);y2Axis.yTickFormat(_)}},duration:{get:function(){return transitionDuration},set:function(_){transitionDuration=_;yAxis.duration(transitionDuration);xAxis.duration(transitionDuration)}},x:{get:function(){return lines.x()},set:function(_){lines.x(_);lines2.x(_)}},y:{get:function(){return lines.y()},set:function(_){lines.y(_);lines2.y(_)}}});nv.utils.inheritOptions(chart,lines);nv.utils.initOptions(chart);return chart};nv.models.multiBar=function(){"use strict";var margin={top:0,right:0,bottom:0,left:0},width=960,height=500,x=d3.scale.ordinal(),y=d3.scale.linear(),id=Math.floor(Math.random()*1e4),getX=function(d){return d.x},getY=function(d){return d.y},forceY=[0],clipEdge=true,stacked=false,stackOffset="zero",color=nv.utils.defaultColor(),hideable=false,barColor=null,disabled,duration=500,xDomain,yDomain,xRange,yRange,groupSpacing=.1,dispatch=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd");var x0,y0,renderWatch=nv.utils.renderWatch(dispatch,duration);var last_datalength=0;function chart(selection){renderWatch.reset();selection.each(function(data){var availableWidth=width-margin.left-margin.right,availableHeight=height-margin.top-margin.bottom,container=d3.select(this);nv.utils.initSVG(container);var endFn=function(d,i){if(d.series===data.length-1&&i===data[0].values.length-1)return true;return false};if(hideable&&data.length)hideable=[{values:data[0].values.map(function(d){return{x:d.x,y:0,series:d.series,size:.01}})}];if(stacked)data=d3.layout.stack().offset(stackOffset).values(function(d){return d.values}).y(getY)(!data.length&&hideable?hideable:data);data.forEach(function(series,i){series.values.forEach(function(point){point.series=i})});if(stacked)data[0].values.map(function(d,i){var posBase=0,negBase=0;data.map(function(d){var f=d.values[i];f.size=Math.abs(f.y);if(f.y<0){f.y1=negBase;negBase=negBase-f.size}else{f.y1=f.size+posBase;posBase=posBase+f.size}})});var seriesData=xDomain&&yDomain?[]:data.map(function(d){return d.values.map(function(d,i){return{x:getX(d,i),y:getY(d,i),y0:d.y0,y1:d.y1}})});x.domain(xDomain||d3.merge(seriesData).map(function(d){return d.x})).rangeBands(xRange||[0,availableWidth],groupSpacing);y.domain(yDomain||d3.extent(d3.merge(seriesData).map(function(d){return stacked?d.y>0?d.y1:d.y1+d.y:d.y}).concat(forceY))).range(yRange||[availableHeight,0]);if(x.domain()[0]===x.domain()[1])x.domain()[0]?x.domain([x.domain()[0]-x.domain()[0]*.01,x.domain()[1]+x.domain()[1]*.01]):x.domain([-1,1]);if(y.domain()[0]===y.domain()[1])y.domain()[0]?y.domain([y.domain()[0]+y.domain()[0]*.01,y.domain()[1]-y.domain()[1]*.01]):y.domain([-1,1]);x0=x0||x;y0=y0||y;var wrap=container.selectAll("g.nv-wrap.nv-multibar").data([data]);var wrapEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar");var defsEnter=wrapEnter.append("defs");var gEnter=wrapEnter.append("g");var g=wrap.select("g");gEnter.append("g").attr("class","nv-groups");wrap.attr("transform","translate("+margin.left+","+margin.top+")");defsEnter.append("clipPath").attr("id","nv-edge-clip-"+id).append("rect");wrap.select("#nv-edge-clip-"+id+" rect").attr("width",availableWidth).attr("height",availableHeight);g.attr("clip-path",clipEdge?"url(#nv-edge-clip-"+id+")":"");var groups=wrap.select(".nv-groups").selectAll(".nv-group").data(function(d){return d},function(d,i){return i});groups.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var exitTransition=renderWatch.transition(groups.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,duration)).attr("y",function(d){return(stacked?y0(d.y0):y0(0))||0}).attr("height",0).remove();if(exitTransition.delay)exitTransition.delay(function(d,i){var delay=i*(duration\/(last_datalength+1))-i;return delay});groups.attr("class",function(d,i){return"nv-group nv-series-"+i}).classed("hover",function(d){return d.hover}).style("fill",function(d,i){return color(d,i)}).style("stroke",function(d,i){return color(d,i)});groups.style("stroke-opacity",1).style("fill-opacity",.75);var bars=groups.selectAll("rect.nv-bar").data(function(d){return hideable&&!data.length?hideable.values:d.values});bars.exit().remove();var barsEnter=bars.enter().append("rect").attr("class",function(d,i){return getY(d,i)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(d,i,j){return stacked?0:j*x.rangeBand()\/data.length}).attr("y",function(d){return y0(stacked?d.y0:0)||0}).attr("height",0).attr("width",x.rangeBand()\/(stacked?1:data.length)).attr("transform",function(d,i){return"translate("+x(getX(d,i))+",0)"});bars.style("fill",function(d,i,j){return color(d,j,i)}).style("stroke",function(d,i,j){return color(d,j,i)}).on("mouseover",function(d,i){d3.select(this).classed("hover",true);dispatch.elementMouseover({value:getY(d,i),point:d,series:data[d.series],pos:[x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length,y(getY(d,i)+(stacked?d.y0:0))],pointIndex:i,seriesIndex:d.series,e:d3.event})}).on("mouseout",function(d,i){d3.select(this).classed("hover",false);dispatch.elementMouseout({value:getY(d,i),point:d,series:data[d.series],pointIndex:i,seriesIndex:d.series,e:d3.event})}).on("click",function(d,i){dispatch.elementClick({value:getY(d,i),point:d,series:data[d.series],pos:[x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length,y(getY(d,i)+(stacked?d.y0:0))],pointIndex:i,seriesIndex:d.series,e:d3.event});d3.event.stopPropagation()}).on("dblclick",function(d,i){dispatch.elementDblClick({value:getY(d,i),point:d,series:data[d.series],pos:[x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length,y(getY(d,i)+(stacked?d.y0:0))],pointIndex:i,seriesIndex:d.series,e:d3.event});d3.event.stopPropagation()});bars.attr("class",function(d,i){return getY(d,i)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(d,i){return"translate("+x(getX(d,i))+",0)"});if(barColor){if(!disabled)disabled=data.map(function(){return true});bars.style("fill",function(d,i,j){return d3.rgb(barColor(d,i)).darker(disabled.map(function(d,i){return i}).filter(function(d,i){return!disabled[i]})[j]).toString()}).style("stroke",function(d,i,j){return d3.rgb(barColor(d,i)).darker(disabled.map(function(d,i){return i}).filter(function(d,i){return!disabled[i]})[j]).toString()})}var barSelection=bars.watchTransition(renderWatch,"multibar",Math.min(250,duration)).delay(function(d,i){return i*duration\/data[0].values.length});if(stacked)barSelection.attr("y",function(d,i){return y(stacked?d.y1:0)}).attr("height",function(d,i){return Math.max(Math.abs(y(d.y+(stacked?d.y0:0))-y(stacked?d.y0:0)),1)}).attr("x",function(d,i){return stacked?0:d.series*x.rangeBand()\/data.length}).attr("width",x.rangeBand()\/(stacked?1:data.length));else barSelection.attr("x",function(d,i){return d.series*x.rangeBand()\/data.length}).attr("width",x.rangeBand()\/data.length).attr("y",function(d,i){return getY(d,i)<0?y(0):y(0)-y(getY(d,i))<1?y(0)-1:y(getY(d,i))||0}).attr("height",function(d,i){return Math.max(Math.abs(y(getY(d,i))-y(0)),1)||0});x0=x.copy();y0=y.copy();if(data[0]&&data[0].values){last_datalength=data[0].values.length}});renderWatch.renderEnd("multibar immediate");return chart}chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},x:{get:function(){return getX},set:function(_){getX=_}},y:{get:function(){return getY},set:function(_){getY=_}},xScale:{get:function(){return x},set:function(_){x=_}},yScale:{get:function(){return y},set:function(_){y=_}},xDomain:{get:function(){return xDomain},set:function(_){xDomain=_}},yDomain:{get:function(){return yDomain},set:function(_){yDomain=_}},xRange:{get:function(){return xRange},set:function(_){xRange=_}},yRange:{get:function(){return yRange},set:function(_){yRange=_}},forceY:{get:function(){return forceY},set:function(_){forceY=_}},stacked:{get:function(){return stacked},set:function(_){stacked=_}},stackOffset:{get:function(){return stackOffset},set:function(_){stackOffset=_}},clipEdge:{get:function(){return clipEdge},set:function(_){clipEdge=_}},disabled:{get:function(){return disabled},set:function(_){disabled=_}},id:{get:function(){return id},set:function(_){id=_}},hideable:{get:function(){return hideable},set:function(_){hideable=_}},groupSpacing:{get:function(){return groupSpacing},set:function(_){groupSpacing=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration)}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_)}},barColor:{get:function(){return barColor},set:function(_){barColor=nv.utils.getColor(_)}}});nv.utils.initOptions(chart);return chart};nv.models.multiBarChart=function(){"use strict";var multibar=nv.models.multiBar(),xAxis=nv.models.axis(),yAxis=nv.models.axis(),legend=nv.models.legend(),controls=nv.models.legend();var margin={top:30,right:20,bottom:50,left:60},width=null,height=null,color=nv.utils.defaultColor(),showControls=true,controlLabels={},showLegend=true,showXAxis=true,showYAxis=true,rightAlignYAxis=false,reduceXTicks=true,staggerLabels=false,rotateLabels=0,tooltips=true,tooltip=function(key,x,y,e,graph){return"

"+key+"<\/h3>"+"

"+y+" on "+x+"<\/p>"},x,y,state=nv.utils.state(),defaultState=null,noData="No Data Available.",dispatch=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),controlWidth=function(){return showControls?180:0},duration=250;state.stacked=false;multibar.stacked(false);xAxis.orient("bottom").tickPadding(7).highlightZero(true).showMaxMin(false).tickFormat(function(d){return d});yAxis.orient(rightAlignYAxis?"right":"left").tickFormat(d3.format(",.1f"));controls.updateState(false);var renderWatch=nv.utils.renderWatch(dispatch);var stacked=false;var showTooltip=function(e,offsetElement){var left=e.pos[0]+(offsetElement.offsetLeft||0),top=e.pos[1]+(offsetElement.offsetTop||0),x=xAxis.tickFormat()(multibar.x()(e.point,e.pointIndex)),y=yAxis.tickFormat()(multibar.y()(e.point,e.pointIndex)),content=tooltip(e.series.key,x,y,e,chart);nv.tooltip.show([left,top],content,e.value<0?"n":"s",null,offsetElement)};var stateGetter=function(data){return function(){return{active:data.map(function(d){return!d.disabled}),stacked:stacked}}};var stateSetter=function(data){return function(state){if(state.stacked!==undefined)stacked=state.stacked;if(state.active!==undefined)data.forEach(function(series,i){series.disabled=!state.active[i]})}};function chart(selection){renderWatch.reset();renderWatch.models(multibar);if(showXAxis)renderWatch.models(xAxis);if(showYAxis)renderWatch.models(yAxis);selection.each(function(data){var container=d3.select(this),that=this;nv.utils.initSVG(container);var availableWidth=(width||parseInt(container.style("width"))||960)-margin.left-margin.right,availableHeight=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom;chart.update=function(){if(duration===0)container.call(chart);else container.transition().duration(duration).call(chart)};chart.container=this;state.setter(stateSetter(data),chart.update).getter(stateGetter(data)).update();state.disabled=data.map(function(d){return!!d.disabled});if(!defaultState){var key;defaultState={};for(key in state){if(state[key]instanceof Array)defaultState[key]=state[key].slice(0);else defaultState[key]=state[key]}}if(!data||!data.length||!data.filter(function(d){return d.values.length}).length){var noDataText=container.selectAll(".nv-noData").data([noData]);noDataText.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle");noDataText.attr("x",margin.left+availableWidth\/2).attr("y",margin.top+availableHeight\/2).text(function(d){return d});return chart}else{container.selectAll(".nv-noData").remove()}x=multibar.xScale();y=multibar.yScale();var wrap=container.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([data]);var gEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g");var g=wrap.select("g");gEnter.append("g").attr("class","nv-x nv-axis");gEnter.append("g").attr("class","nv-y nv-axis");gEnter.append("g").attr("class","nv-barsWrap");gEnter.append("g").attr("class","nv-legendWrap");gEnter.append("g").attr("class","nv-controlsWrap");if(showLegend){legend.width(availableWidth-controlWidth());if(multibar.barColor())data.forEach(function(series,i){series.color=d3.rgb("#ccc").darker(i*1.5).toString()});g.select(".nv-legendWrap").datum(data).call(legend);if(margin.top!=legend.height()){margin.top=legend.height();availableHeight=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom}g.select(".nv-legendWrap").attr("transform","translate("+controlWidth()+","+-margin.top+")")}if(showControls){var controlsData=[{key:controlLabels.grouped||"Grouped",disabled:multibar.stacked()},{key:controlLabels.stacked||"Stacked",disabled:!multibar.stacked()}];controls.width(controlWidth()).color(["#444","#444","#444"]);g.select(".nv-controlsWrap").datum(controlsData).attr("transform","translate(0,"+-margin.top+")").call(controls)}wrap.attr("transform","translate("+margin.left+","+margin.top+")");if(rightAlignYAxis){g.select(".nv-y.nv-axis").attr("transform","translate("+availableWidth+",0)")}multibar.disabled(data.map(function(series){return series.disabled})).width(availableWidth).height(availableHeight).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled}));var barsWrap=g.select(".nv-barsWrap").datum(data.filter(function(d){return!d.disabled}));barsWrap.call(multibar);if(showXAxis){xAxis.scale(x).ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight,0);g.select(".nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")");g.select(".nv-x.nv-axis").call(xAxis);var xTicks=g.select(".nv-x.nv-axis > g").selectAll("g");xTicks.selectAll("line, text").style("opacity",1);if(staggerLabels){var getTranslate=function(x,y){return"translate("+x+","+y+")"};var staggerUp=5,staggerDown=17;xTicks.selectAll("text").attr("transform",function(d,i,j){return getTranslate(0,j%2==0?staggerUp:staggerDown)});var totalInBetweenTicks=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;g.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(d,i){return getTranslate(0,i===0||totalInBetweenTicks%2!==0?staggerDown:staggerUp)})}if(reduceXTicks)xTicks.filter(function(d,i){return i%Math.ceil(data[0].values.length\/(availableWidth\/100))!==0}).selectAll("text, line").style("opacity",0);if(rotateLabels)xTicks.selectAll(".tick text").attr("transform","rotate("+rotateLabels+" 0,0)").style("text-anchor",rotateLabels>0?"start":"end");g.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}if(showYAxis){yAxis.scale(y).ticks(nv.utils.calcTicksY(availableHeight\/36,data)).tickSize(-availableWidth,0);g.select(".nv-y.nv-axis").call(yAxis)}legend.dispatch.on("stateChange",function(newState){for(var key in newState)state[key]=newState[key];dispatch.stateChange(state);chart.update()});controls.dispatch.on("legendClick",function(d,i){if(!d.disabled)return;controlsData=controlsData.map(function(s){s.disabled=true;return s});d.disabled=false;switch(d.key){case"Grouped":multibar.stacked(false);break;case"Stacked":multibar.stacked(true);break}state.stacked=multibar.stacked();dispatch.stateChange(state);chart.update()});dispatch.on("tooltipShow",function(e){if(tooltips)showTooltip(e,that.parentNode)});dispatch.on("changeState",function(e){if(typeof e.disabled!=="undefined"){data.forEach(function(series,i){series.disabled=e.disabled[i]});state.disabled=e.disabled}if(typeof e.stacked!=="undefined"){multibar.stacked(e.stacked);state.stacked=e.stacked;stacked=e.stacked}chart.update()})});renderWatch.renderEnd("multibarchart immediate");return chart}multibar.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+margin.left,e.pos[1]+margin.top];dispatch.tooltipShow(e)});multibar.dispatch.on("elementMouseout.tooltip",function(e){dispatch.tooltipHide(e)});dispatch.on("tooltipHide",function(){if(tooltips)nv.tooltip.cleanup()});chart.dispatch=dispatch;chart.multibar=multibar;chart.legend=legend;chart.xAxis=xAxis;chart.yAxis=yAxis;chart.state=state;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},showLegend:{get:function(){return showLegend},set:function(_){showLegend=_}},showControls:{get:function(){return showControls},set:function(_){showControls=_}},controlLabels:{get:function(){return controlLabels},set:function(_){controlLabels=_}},showXAxis:{get:function(){return showXAxis},set:function(_){showXAxis=_}},showYAxis:{get:function(){return showYAxis},set:function(_){showYAxis=_}},tooltips:{get:function(){return tooltips},set:function(_){tooltips=_}},tooltipContent:{get:function(){return tooltip},set:function(_){tooltip=_}},defaultState:{get:function(){return defaultState},set:function(_){defaultState=_}},noData:{get:function(){return noData},set:function(_){noData=_}},reduceXTicks:{get:function(){return reduceXTicks},set:function(_){reduceXTicks=_}},rotateLabels:{get:function(){return rotateLabels},set:function(_){rotateLabels=_}},staggerLabels:{get:function(){return staggerLabels},set:function(_){staggerLabels=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;multibar.duration(duration);xAxis.duration(duration);yAxis.duration(duration);renderWatch.reset(duration)}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_);legend.color(color)}},rightAlignYAxis:{get:function(){return rightAlignYAxis},set:function(_){rightAlignYAxis=_;yAxis.orient(rightAlignYAxis?"right":"left")}}});nv.utils.inheritOptions(chart,multibar);nv.utils.initOptions(chart);return chart};nv.models.multiBarHorizontal=function(){"use strict";var margin={top:0,right:0,bottom:0,left:0},width=960,height=500,id=Math.floor(Math.random()*1e4),x=d3.scale.ordinal(),y=d3.scale.linear(),getX=function(d){return d.x},getY=function(d){return d.y},getYerr=function(d){return d.yErr},forceY=[0],color=nv.utils.defaultColor(),barColor=null,disabled,stacked=false,showValues=false,showBarLabels=false,valuePadding=60,valueFormat=d3.format(",.2f"),delay=1200,xDomain,yDomain,xRange,yRange,duration=250,dispatch=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd");var x0,y0;var renderWatch=nv.utils.renderWatch(dispatch,duration);function chart(selection){renderWatch.reset();selection.each(function(data){var availableWidth=width-margin.left-margin.right,availableHeight=height-margin.top-margin.bottom,container=d3.select(this);nv.utils.initSVG(container);if(stacked)data=d3.layout.stack().offset("zero").values(function(d){return d.values}).y(getY)(data);data.forEach(function(series,i){series.values.forEach(function(point){point.series=i})});if(stacked)data[0].values.map(function(d,i){var posBase=0,negBase=0;data.map(function(d){var f=d.values[i];f.size=Math.abs(f.y);if(f.y<0){f.y1=negBase-f.size;negBase=negBase-f.size}else{f.y1=posBase;posBase=posBase+f.size}})});var seriesData=xDomain&&yDomain?[]:data.map(function(d){return d.values.map(function(d,i){return{x:getX(d,i),y:getY(d,i),y0:d.y0,y1:d.y1}})});x.domain(xDomain||d3.merge(seriesData).map(function(d){return d.x})).rangeBands(xRange||[0,availableHeight],.1);y.domain(yDomain||d3.extent(d3.merge(seriesData).map(function(d){return stacked?d.y>0?d.y1+d.y:d.y1:d.y}).concat(forceY)));if(showValues&&!stacked)y.range(yRange||[y.domain()[0]<0?valuePadding:0,availableWidth-(y.domain()[1]>0?valuePadding:0)]);else y.range(yRange||[0,availableWidth]);x0=x0||x;y0=y0||d3.scale.linear().domain(y.domain()).range([y(0),y(0)]);var wrap=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([data]);var wrapEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal");var defsEnter=wrapEnter.append("defs");var gEnter=wrapEnter.append("g");var g=wrap.select("g");gEnter.append("g").attr("class","nv-groups");wrap.attr("transform","translate("+margin.left+","+margin.top+")");var groups=wrap.select(".nv-groups").selectAll(".nv-group").data(function(d){return d},function(d,i){return i});groups.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);groups.exit().watchTransition(renderWatch,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove();groups.attr("class",function(d,i){return"nv-group nv-series-"+i}).classed("hover",function(d){return d.hover}).style("fill",function(d,i){return color(d,i)}).style("stroke",function(d,i){return color(d,i)});groups.watchTransition(renderWatch,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var bars=groups.selectAll("g.nv-bar").data(function(d){return d.values});bars.exit().remove();var barsEnter=bars.enter().append("g").attr("transform",function(d,i,j){return"translate("+y0(stacked?d.y0:0)+","+(stacked?0:j*x.rangeBand()\/data.length+x(getX(d,i)))+")"});barsEnter.append("rect").attr("width",0).attr("height",x.rangeBand()\/(stacked?1:data.length));bars.on("mouseover",function(d,i){d3.select(this).classed("hover",true);dispatch.elementMouseover({value:getY(d,i),point:d,series:data[d.series],pos:[y(getY(d,i)+(stacked?d.y0:0)),x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length],pointIndex:i,seriesIndex:d.series,e:d3.event})}).on("mouseout",function(d,i){d3.select(this).classed("hover",false);dispatch.elementMouseout({value:getY(d,i),point:d,series:data[d.series],pointIndex:i,seriesIndex:d.series,e:d3.event})}).on("click",function(d,i){dispatch.elementClick({value:getY(d,i),point:d,series:data[d.series],pos:[x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length,y(getY(d,i)+(stacked?d.y0:0))],pointIndex:i,seriesIndex:d.series,e:d3.event});d3.event.stopPropagation()}).on("dblclick",function(d,i){dispatch.elementDblClick({value:getY(d,i),point:d,series:data[d.series],pos:[x(getX(d,i))+x.rangeBand()*(stacked?data.length\/2:d.series+.5)\/data.length,y(getY(d,i)+(stacked?d.y0:0))],pointIndex:i,seriesIndex:d.series,e:d3.event});d3.event.stopPropagation()});if(getYerr(data[0],0)){barsEnter.append("polyline");bars.select("polyline").attr("fill","none").attr("points",function(d,i){var xerr=getYerr(d,i),mid=.8*x.rangeBand()\/((stacked?1:data.length)*2);xerr=xerr.length?xerr:[-Math.abs(xerr),Math.abs(xerr)];xerr=xerr.map(function(e){return y(e)-y(0)});var a=[[xerr[0],-mid],[xerr[0],mid],[xerr[0],0],[xerr[1],0],[xerr[1],-mid],[xerr[1],mid]];return a.map(function(path){return path.join(",")}).join(" ")}).attr("transform",function(d,i){var mid=x.rangeBand()\/((stacked?1:data.length)*2);return"translate("+(getY(d,i)<0?0:y(getY(d,i))-y(0))+", "+mid+")"})}barsEnter.append("text");if(showValues&&!stacked){bars.select("text").attr("text-anchor",function(d,i){return getY(d,i)<0?"end":"start"}).attr("y",x.rangeBand()\/(data.length*2)).attr("dy",".32em").html(function(d,i){var t=valueFormat(getY(d,i)),yerr=getYerr(d,i);if(yerr===undefined)return t;if(!yerr.length)return t+"±"+valueFormat(Math.abs(yerr));return t+"+"+valueFormat(Math.abs(yerr[1]))+"-"+valueFormat(Math.abs(yerr[0]))});bars.watchTransition(renderWatch,"multibarhorizontal: bars").select("text").attr("x",function(d,i){return getY(d,i)<0?-4:y(getY(d,i))-y(0)+4})}else{bars.selectAll("text").text("")}if(showBarLabels&&!stacked){barsEnter.append("text").classed("nv-bar-label",true);bars.select("text.nv-bar-label").attr("text-anchor",function(d,i){return getY(d,i)<0?"start":"end"}).attr("y",x.rangeBand()\/(data.length*2)).attr("dy",".32em").text(function(d,i){return getX(d,i)});bars.watchTransition(renderWatch,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(d,i){return getY(d,i)<0?y(0)-y(getY(d,i))+4:-4})}else{bars.selectAll("text.nv-bar-label").text("")}bars.attr("class",function(d,i){return getY(d,i)<0?"nv-bar negative":"nv-bar positive"});if(barColor){if(!disabled)disabled=data.map(function(){return true});bars.style("fill",function(d,i,j){return d3.rgb(barColor(d,i)).darker(disabled.map(function(d,i){return i}).filter(function(d,i){return!disabled[i]})[j]).toString()}).style("stroke",function(d,i,j){return d3.rgb(barColor(d,i)).darker(disabled.map(function(d,i){return i}).filter(function(d,i){return!disabled[i]})[j]).toString()})}if(stacked)bars.watchTransition(renderWatch,"multibarhorizontal: bars").attr("transform",function(d,i){return"translate("+y(d.y1)+","+x(getX(d,i))+")"}).select("rect").attr("width",function(d,i){return Math.abs(y(getY(d,i)+d.y0)-y(d.y0))}).attr("height",x.rangeBand());else bars.watchTransition(renderWatch,"multibarhorizontal: bars").attr("transform",function(d,i){return"translate("+(getY(d,i)<0?y(getY(d,i)):y(0))+","+(d.series*x.rangeBand()\/data.length+x(getX(d,i)))+")"}).select("rect").attr("height",x.rangeBand()\/data.length).attr("width",function(d,i){return Math.max(Math.abs(y(getY(d,i))-y(0)),1)});x0=x.copy();y0=y.copy()});renderWatch.renderEnd("multibarHorizontal immediate");return chart}chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},x:{get:function(){return getX},set:function(_){getX=_}},y:{get:function(){return getY},set:function(_){getY=_}},yErr:{get:function(){return getYerr},set:function(_){getYerr=_}},xScale:{get:function(){return x},set:function(_){x=_}},yScale:{get:function(){return y},set:function(_){y=_}},xDomain:{get:function(){return xDomain},set:function(_){xDomain=_}},yDomain:{get:function(){return yDomain},set:function(_){yDomain=_}},xRange:{get:function(){return xRange},set:function(_){xRange=_}},yRange:{get:function(){return yRange},set:function(_){yRange=_}},forceY:{get:function(){return forceY},set:function(_){forceY=_}},stacked:{get:function(){return stacked},set:function(_){stacked=_}},showValues:{get:function(){return showValues},set:function(_){showValues=_}},disabled:{get:function(){return disabled},set:function(_){disabled=_}},id:{get:function(){return id},set:function(_){id=_}},valueFormat:{get:function(){return valueFormat},set:function(_){valueFormat=_}},valuePadding:{get:function(){return valuePadding},set:function(_){valuePadding=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration)}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_)}},barColor:{get:function(){return color},set:function(_){barColor=nv.utils.getColor(_)}}});nv.utils.initOptions(chart);return chart};nv.models.multiBarHorizontalChart=function(){"use strict";var multibar=nv.models.multiBarHorizontal(),xAxis=nv.models.axis(),yAxis=nv.models.axis(),legend=nv.models.legend().height(30),controls=nv.models.legend().height(30);var margin={top:30,right:20,bottom:50,left:60},width=null,height=null,color=nv.utils.defaultColor(),showControls=true,controlLabels={},showLegend=true,showXAxis=true,showYAxis=true,stacked=false,tooltips=true,tooltip=function(key,x,y,e,graph){return"

"+key+" - "+x+"<\/h3>"+"

"+y+"<\/p>"},x,y,state=nv.utils.state(),defaultState=null,noData="No Data Available.",dispatch=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),controlWidth=function(){return showControls?180:0},duration=250;state.stacked=false;multibar.stacked(stacked);xAxis.orient("left").tickPadding(5).highlightZero(false).showMaxMin(false).tickFormat(function(d){return d});yAxis.orient("bottom").tickFormat(d3.format(",.1f"));controls.updateState(false);var showTooltip=function(e,offsetElement){var left=e.pos[0]+(offsetElement.offsetLeft||0),top=e.pos[1]+(offsetElement.offsetTop||0),x=xAxis.tickFormat()(multibar.x()(e.point,e.pointIndex)),y=yAxis.tickFormat()(multibar.y()(e.point,e.pointIndex)),content=tooltip(e.series.key,x,y,e,chart);nv.tooltip.show([left,top],content,e.value<0?"e":"w",null,offsetElement)};var stateGetter=function(data){return function(){return{active:data.map(function(d){return!d.disabled}),stacked:stacked}}};var stateSetter=function(data){return function(state){if(state.stacked!==undefined)stacked=state.stacked;if(state.active!==undefined)data.forEach(function(series,i){series.disabled=!state.active[i]})}};var renderWatch=nv.utils.renderWatch(dispatch,duration);function chart(selection){renderWatch.reset();renderWatch.models(multibar);if(showXAxis)renderWatch.models(xAxis);if(showYAxis)renderWatch.models(yAxis);selection.each(function(data){var container=d3.select(this),that=this;nv.utils.initSVG(container);var availableWidth=(width||parseInt(container.style("width"))||960)-margin.left-margin.right,availableHeight=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom;chart.update=function(){container.transition().duration(duration).call(chart)};chart.container=this;stacked=multibar.stacked();state.setter(stateSetter(data),chart.update).getter(stateGetter(data)).update();state.disabled=data.map(function(d){return!!d.disabled});if(!defaultState){var key;defaultState={};for(key in state){if(state[key]instanceof Array)defaultState[key]=state[key].slice(0);else defaultState[key]=state[key]}}if(!data||!data.length||!data.filter(function(d){return d.values.length}).length){var noDataText=container.selectAll(".nv-noData").data([noData]);noDataText.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle");noDataText.attr("x",margin.left+availableWidth\/2).attr("y",margin.top+availableHeight\/2).text(function(d){return d});return chart}else{container.selectAll(".nv-noData").remove()$/;" m nv phpunit/coverage/js/nv.d3.min.js /^},set:function(_){clipEdge=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration);scatter.duration(duration)}},isArea:{get:function(){return isArea},set:function(_){isArea=d3.functor(_)}},x:{get:function(){return getX},set:function(_){getX=_;scatter.x(_)}},y:{get:function(){return getY},set:function(_){getY=_;scatter.y(_)}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_);scatter.color(color)}}});nv.utils.inheritOptions(chart,scatter);nv.utils.initOptions(chart);return chart};nv.models.lineChart=function(){"use strict";var lines=nv.models.line(),xAxis=nv.models.axis(),yAxis=nv.models.axis(),legend=nv.models.legend(),interactiveLayer=nv.interactiveGuideline();var margin={top:30,right:20,bottom:50,left:60},color=nv.utils.defaultColor(),width=null,height=null,showLegend=true,showXAxis=true,showYAxis=true,rightAlignYAxis=false,useInteractiveGuideline=false,tooltips=true,tooltip=function(key,x,y,e,graph){return"

"+key+"<\/h3>"+"

"+y+" at "+x+"<\/p>"},x,y,state=nv.utils.state(),defaultState=null,noData="No Data Available.",dispatch=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),duration=250;xAxis.orient("bottom").tickPadding(7);yAxis.orient(rightAlignYAxis?"right":"left");var showTooltip=function(e,offsetElement){var left=e.pos[0]+(offsetElement.offsetLeft||0),top=e.pos[1]+(offsetElement.offsetTop||0),x=xAxis.tickFormat()(lines.x()(e.point,e.pointIndex)),y=yAxis.tickFormat()(lines.y()(e.point,e.pointIndex)),content=tooltip(e.series.key,x,y,e,chart);nv.tooltip.show([left,top],content,null,null,offsetElement)};var renderWatch=nv.utils.renderWatch(dispatch,duration);var stateGetter=function(data){return function(){return{active:data.map(function(d){return!d.disabled})}}};var stateSetter=function(data){return function(state){if(state.active!==undefined)data.forEach(function(series,i){series.disabled=!state.active[i]})}};function chart(selection){renderWatch.reset();renderWatch.models(lines);if(showXAxis)renderWatch.models(xAxis);if(showYAxis)renderWatch.models(yAxis);selection.each(function(data){var container=d3.select(this),that=this;nv.utils.initSVG(container);var availableWidth=(width||parseInt(container.style("width"))||960)-margin.left-margin.right,availableHeight=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom;chart.update=function(){if(duration===0)container.call(chart);else container.transition().duration(duration).call(chart)};chart.container=this;state.setter(stateSetter(data),chart.update).getter(stateGetter(data)).update();state.disabled=data.map(function(d){return!!d.disabled});if(!defaultState){var key;defaultState={};for(key in state){if(state[key]instanceof Array)defaultState[key]=state[key].slice(0);else defaultState[key]=state[key]}}if(!data||!data.length||!data.filter(function(d){return d.values.length}).length){var noDataText=container.selectAll(".nv-noData").data([noData]);noDataText.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle");noDataText.attr("x",margin.left+availableWidth\/2).attr("y",margin.top+availableHeight\/2).text(function(d){return d});return chart}else{container.selectAll(".nv-noData").remove()}x=lines.xScale();y=lines.yScale();var wrap=container.selectAll("g.nv-wrap.nv-lineChart").data([data]);var gEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g");var g=wrap.select("g");gEnter.append("rect").style("opacity",0);gEnter.append("g").attr("class","nv-x nv-axis");gEnter.append("g").attr("class","nv-y nv-axis");gEnter.append("g").attr("class","nv-linesWrap");gEnter.append("g").attr("class","nv-legendWrap");gEnter.append("g").attr("class","nv-interactive");g.select("rect").attr("width",availableWidth).attr("height",availableHeight>0?availableHeight:0);if(showLegend){legend.width(availableWidth);g.select(".nv-legendWrap").datum(data).call(legend);if(margin.top!=legend.height()){margin.top=legend.height();availableHeight=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom}wrap.select(".nv-legendWrap").attr("transform","translate(0,"+-margin.top+")")}wrap.attr("transform","translate("+margin.left+","+margin.top+")");if(rightAlignYAxis){g.select(".nv-y.nv-axis").attr("transform","translate("+availableWidth+",0)")}if(useInteractiveGuideline){interactiveLayer.width(availableWidth).height(availableHeight).margin({left:margin.left,top:margin.top}).svgContainer(container).xScale(x);wrap.select(".nv-interactive").call(interactiveLayer)}lines.width(availableWidth).height(availableHeight).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled}));var linesWrap=g.select(".nv-linesWrap").datum(data.filter(function(d){return!d.disabled}));linesWrap.call(lines);if(showXAxis){xAxis.scale(x).ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight,0);g.select(".nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")");g.select(".nv-x.nv-axis").call(xAxis)}if(showYAxis){yAxis.scale(y).ticks(nv.utils.calcTicksY(availableHeight\/36,data)).tickSize(-availableWidth,0);g.select(".nv-y.nv-axis").call(yAxis)}legend.dispatch.on("stateChange",function(newState){for(var key in newState)state[key]=newState[key];dispatch.stateChange(state);chart.update()});interactiveLayer.dispatch.on("elementMousemove",function(e){lines.clearHighlights();var singlePoint,pointIndex,pointXLocation,allData=[];data.filter(function(series,i){series.seriesIndex=i;return!series.disabled}).forEach(function(series,i){pointIndex=nv.interactiveBisect(series.values,e.pointXValue,chart.x());lines.highlightPoint(i,pointIndex,true);var point=series.values[pointIndex];if(typeof point==="undefined")return;if(typeof singlePoint==="undefined")singlePoint=point;if(typeof pointXLocation==="undefined")pointXLocation=chart.xScale()(chart.x()(point,pointIndex));allData.push({key:series.key,value:chart.y()(point,pointIndex),color:color(series,series.seriesIndex)})});if(allData.length>2){var yValue=chart.yScale().invert(e.mouseY);var domainExtent=Math.abs(chart.yScale().domain()[0]-chart.yScale().domain()[1]);var threshold=.03*domainExtent;var indexToHighlight=nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold);if(indexToHighlight!==null)allData[indexToHighlight].highlight=true}var xValue=xAxis.tickFormat()(chart.x()(singlePoint,pointIndex));interactiveLayer.tooltip.position({left:pointXLocation+margin.left,top:e.mouseY+margin.top}).chartContainer(that.parentNode).enabled(tooltips).valueFormatter(function(d,i){return yAxis.tickFormat()(d)}).data({value:xValue,series:allData})();interactiveLayer.renderGuideLine(pointXLocation)});interactiveLayer.dispatch.on("elementClick",function(e){var pointXLocation,allData=[];data.filter(function(series,i){series.seriesIndex=i;return!series.disabled}).forEach(function(series){var pointIndex=nv.interactiveBisect(series.values,e.pointXValue,chart.x());var point=series.values[pointIndex];if(typeof point==="undefined")return;if(typeof pointXLocation==="undefined")pointXLocation=chart.xScale()(chart.x()(point,pointIndex));var yPos=chart.yScale()(chart.y()(point,pointIndex));allData.push({point:point,pointIndex:pointIndex,pos:[pointXLocation,yPos],seriesIndex:series.seriesIndex,series:series})});lines.dispatch.elementClick(allData)});interactiveLayer.dispatch.on("elementMouseout",function(e){dispatch.tooltipHide();lines.clearHighlights()});dispatch.on("tooltipShow",function(e){if(tooltips)showTooltip(e,that.parentNode)});dispatch.on("changeState",function(e){if(typeof e.disabled!=="undefined"&&data.length===e.disabled.length){data.forEach(function(series,i){series.disabled=e.disabled[i]});state.disabled=e.disabled}chart.update()})});renderWatch.renderEnd("lineChart immediate");return chart}lines.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+margin.left,e.pos[1]+margin.top];dispatch.tooltipShow(e)});lines.dispatch.on("elementMouseout.tooltip",function(e){dispatch.tooltipHide(e)});dispatch.on("tooltipHide",function(){if(tooltips)nv.tooltip.cleanup()});chart.dispatch=dispatch;chart.lines=lines;chart.legend=legend;chart.xAxis=xAxis;chart.yAxis=yAxis;chart.interactiveLayer=interactiveLayer;chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},showLegend:{get:function(){return showLegend},set:function(_){showLegend=_}},showXAxis:{get:function(){return showXAxis},set:function(_){showXAxis=_}},showYAxis:{get:function(){return showYAxis},set:function(_){showYAxis=_}},tooltips:{get:function(){return tooltips},set:function(_){tooltips=_}},tooltipContent:{get:function(){return tooltip},set:function(_){tooltip=_}},defaultState:{get:function(){return defaultState},set:function(_){defaultState=_}},noData:{get:function(){return noData},set:function(_){noData=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration);lines.duration(duration);xAxis.duration(duration);yAxis.duration(duration)}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_);legend.color(color);lines.color(color)}},rightAlignYAxis:{get:function(){return rightAlignYAxis},set:function(_){rightAlignYAxis=_;yAxis.orient(rightAlignYAxis?"right":"left")}},useInteractiveGuideline:{get:function(){return useInteractiveGuideline},set:function(_){useInteractiveGuideline=_;if(useInteractiveGuideline){lines.interactive(false);lines.useVoronoi(false)}}}});nv.utils.inheritOptions(chart,lines);nv.utils.initOptions(chart);return chart};nv.models.linePlusBarChart=function(){"use strict";var lines=nv.models.line(),lines2=nv.models.line(),bars=nv.models.historicalBar(),bars2=nv.models.historicalBar(),xAxis=nv.models.axis(),x2Axis=nv.models.axis(),y1Axis=nv.models.axis(),y2Axis=nv.models.axis(),y3Axis=nv.models.axis(),y4Axis=nv.models.axis(),legend=nv.models.legend(),brush=d3.svg.brush();var margin={top:30,right:30,bottom:30,left:60},margin2={top:0,right:30,bottom:20,left:60},width=null,height=null,getX=function(d){return d.x},getY=function(d){return d.y},color=nv.utils.defaultColor(),showLegend=true,focusEnable=true,focusShowAxisY=false,focusShowAxisX=true,focusHeight=50,extent,brushExtent=null,tooltips=true,tooltip=function(key,x,y,e,graph){return"

"+key+"<\/h3>"+"

"+y+" at "+x+"<\/p>"},x,x2,y1,y2,y3,y4,noData="No Data Available.",dispatch=d3.dispatch("tooltipShow","tooltipHide","brush","stateChange","changeState"),transitionDuration=0,state=nv.utils.state(),defaultState=null,legendLeftAxisHint=" (left axis)",legendRightAxisHint=" (right axis)";lines.clipEdge(true);lines2.interactive(false);xAxis.orient("bottom").tickPadding(5);y1Axis.orient("left");y2Axis.orient("right");x2Axis.orient("bottom").tickPadding(5);y3Axis.orient("left");y4Axis.orient("right");var showTooltip=function(e,offsetElement){if(extent){e.pointIndex+=Math.ceil(extent[0])}var left=e.pos[0]+(offsetElement.offsetLeft||0),top=e.pos[1]+(offsetElement.offsetTop||0),x=xAxis.tickFormat()(lines.x()(e.point,e.pointIndex)),y=(e.series.bar?y1Axis:y2Axis).tickFormat()(lines.y()(e.point,e.pointIndex)),content=tooltip(e.series.key,x,y,e,chart);nv.tooltip.show([left,top],content,e.value<0?"n":"s",null,offsetElement)};var stateGetter=function(data){return function(){return{active:data.map(function(d){return!d.disabled})}}};var stateSetter=function(data){return function(state){if(state.active!==undefined)data.forEach(function(series,i){series.disabled=!state.active[i]})}};function chart(selection){selection.each(function(data){var container=d3.select(this),that=this;nv.utils.initSVG(container);var availableWidth=(width||parseInt(container.style("width"))||960)-margin.left-margin.right,availableHeight1=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom-(focusEnable?focusHeight:0),availableHeight2=focusHeight-margin2.top-margin2.bottom;chart.update=function(){container.transition().duration(transitionDuration).call(chart)};chart.container=this;state.setter(stateSetter(data),chart.update).getter(stateGetter(data)).update();state.disabled=data.map(function(d){return!!d.disabled});if(!defaultState){var key;defaultState={};for(key in state){if(state[key]instanceof Array)defaultState[key]=state[key].slice(0);else defaultState[key]=state[key]}}if(!data||!data.length||!data.filter(function(d){return d.values.length}).length){var noDataText=container.selectAll(".nv-noData").data([noData]);noDataText.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle");noDataText.attr("x",margin.left+availableWidth\/2).attr("y",margin.top+availableHeight1\/2).text(function(d){return d});return chart}else{container.selectAll(".nv-noData").remove()}var dataBars=data.filter(function(d){return!d.disabled&&d.bar});var dataLines=data.filter(function(d){return!d.bar});x=bars.xScale();x2=x2Axis.scale();y1=bars.yScale();y2=lines.yScale();y3=bars2.yScale();y4=lines2.yScale();var series1=data.filter(function(d){return!d.disabled&&d.bar}).map(function(d){return d.values.map(function(d,i){return{x:getX(d,i),y:getY(d,i)}})});var series2=data.filter(function(d){return!d.disabled&&!d.bar}).map(function(d){return d.values.map(function(d,i){return{x:getX(d,i),y:getY(d,i)}})});x.range([0,availableWidth]);x2.domain(d3.extent(d3.merge(series1.concat(series2)),function(d){return d.x})).range([0,availableWidth]);var wrap=container.selectAll("g.nv-wrap.nv-linePlusBar").data([data]);var gEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g");var g=wrap.select("g");gEnter.append("g").attr("class","nv-legendWrap");var focusEnter=gEnter.append("g").attr("class","nv-focus");focusEnter.append("g").attr("class","nv-x nv-axis");focusEnter.append("g").attr("class","nv-y1 nv-axis");focusEnter.append("g").attr("class","nv-y2 nv-axis");focusEnter.append("g").attr("class","nv-barsWrap");focusEnter.append("g").attr("class","nv-linesWrap");var contextEnter=gEnter.append("g").attr("class","nv-context");contextEnter.append("g").attr("class","nv-x nv-axis");contextEnter.append("g").attr("class","nv-y1 nv-axis");contextEnter.append("g").attr("class","nv-y2 nv-axis");contextEnter.append("g").attr("class","nv-barsWrap");contextEnter.append("g").attr("class","nv-linesWrap");contextEnter.append("g").attr("class","nv-brushBackground");contextEnter.append("g").attr("class","nv-x nv-brush");if(showLegend){legend.width(availableWidth\/2);g.select(".nv-legendWrap").datum(data.map(function(series){series.originalKey=series.originalKey===undefined?series.key:series.originalKey;series.key=series.originalKey+(series.bar?legendLeftAxisHint:legendRightAxisHint);return series})).call(legend);if(margin.top!=legend.height()){margin.top=legend.height();availableHeight1=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom-focusHeight}g.select(".nv-legendWrap").attr("transform","translate("+availableWidth\/2+","+-margin.top+")")}wrap.attr("transform","translate("+margin.left+","+margin.top+")");g.select(".nv-context").style("display",focusEnable?"initial":"none");bars2.width(availableWidth).height(availableHeight2).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled&&data[i].bar}));lines2.width(availableWidth).height(availableHeight2).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled&&!data[i].bar}));var bars2Wrap=g.select(".nv-context .nv-barsWrap").datum(dataBars.length?dataBars:[{values:[]}]);var lines2Wrap=g.select(".nv-context .nv-linesWrap").datum(!dataLines[0].disabled?dataLines:[{values:[]}]);g.select(".nv-context").attr("transform","translate(0,"+(availableHeight1+margin.bottom+margin2.top)+")");bars2Wrap.transition().call(bars2);lines2Wrap.transition().call(lines2);if(focusShowAxisX){x2Axis.ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight2,0);g.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y3.range()[0]+")");g.select(".nv-context .nv-x.nv-axis").transition().call(x2Axis)}if(focusShowAxisY){y3Axis.scale(y3).ticks(availableHeight2\/36).tickSize(-availableWidth,0);y4Axis.scale(y4).ticks(availableHeight2\/36).tickSize(dataBars.length?0:-availableWidth,0);g.select(".nv-context .nv-y3.nv-axis").style("opacity",dataBars.length?1:0).attr("transform","translate(0,"+x2.range()[0]+")");g.select(".nv-context .nv-y2.nv-axis").style("opacity",dataLines.length?1:0).attr("transform","translate("+x2.range()[1]+",0)");g.select(".nv-context .nv-y1.nv-axis").transition().call(y3Axis);g.select(".nv-context .nv-y2.nv-axis").transition().call(y4Axis)}brush.x(x2).on("brush",onBrush);if(brushExtent)brush.extent(brushExtent);var brushBG=g.select(".nv-brushBackground").selectAll("g").data([brushExtent||brush.extent()]);var brushBGenter=brushBG.enter().append("g");brushBGenter.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",availableHeight2);brushBGenter.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",availableHeight2);var gBrush=g.select(".nv-x.nv-brush").call(brush);gBrush.selectAll("rect").attr("height",availableHeight2);gBrush.selectAll(".resize").append("path").attr("d",resizePath);legend.dispatch.on("stateChange",function(newState){for(var key in newState)state[key]=newState[key];dispatch.stateChange(state);chart.update()});dispatch.on("tooltipShow",function(e){if(tooltips)showTooltip(e,that.parentNode)});dispatch.on("changeState",function(e){if(typeof e.disabled!=="undefined"){data.forEach(function(series,i){series.disabled=e.disabled[i]});state.disabled=e.disabled}chart.update()});function resizePath(d){var e=+(d=="e"),x=e?1:-1,y=availableHeight2\/3;return"M"+.5*x+","+y+"A6,6 0 0 "+e+" "+6.5*x+","+(y+6)+"V"+(2*y-6)+"A6,6 0 0 "+e+" "+.5*x+","+2*y+"Z"+"M"+2.5*x+","+(y+8)+"V"+(2*y-8)+"M"+4.5*x+","+(y+8)+"V"+(2*y-8)}function updateBrushBG(){if(!brush.empty())brush.extent(brushExtent);brushBG.data([brush.empty()?x2.domain():brushExtent]).each(function(d,i){var leftWidth=x2(d[0])-x2.range()[0],rightWidth=x2.range()[1]-x2(d[1]);d3.select(this).select(".left").attr("width",leftWidth<0?0:leftWidth);d3.select(this).select(".right").attr("x",x2(d[1])).attr("width",rightWidth<0?0:rightWidth)})}function onBrush(){brushExtent=brush.empty()?null:brush.extent();extent=brush.empty()?x2.domain():brush.extent();dispatch.brush({extent:extent,brush:brush});updateBrushBG();bars.width(availableWidth).height(availableHeight1).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled&&data[i].bar}));lines.width(availableWidth).height(availableHeight1).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled&&!data[i].bar}));var focusBarsWrap=g.select(".nv-focus .nv-barsWrap").datum(!dataBars.length?[{values:[]}]:dataBars.map(function(d,i){return{key:d.key,values:d.values.filter(function(d,i){return bars.x()(d,i)>=extent[0]&&bars.x()(d,i)<=extent[1]})}}));var focusLinesWrap=g.select(".nv-focus .nv-linesWrap").datum(dataLines[0].disabled?[{values:[]}]:dataLines.map(function(d,i){return{key:d.key,values:d.values.filter(function(d,i){return lines.x()(d,i)>=extent[0]&&lines.x()(d,i)<=extent[1]})}}));if(dataBars.length){x=bars.xScale()}else{x=lines.xScale()}xAxis.scale(x).ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight1,0);xAxis.domain([Math.ceil(extent[0]),Math.floor(extent[1])]);g.select(".nv-x.nv-axis").transition().duration(transitionDuration).call(xAxis);focusBarsWrap.transition().duration(transitionDuration).call(bars);focusLinesWrap.transition().duration(transitionDuration).call(lines);g.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+y1.range()[0]+")");y1Axis.scale(y1).ticks(nv.utils.calcTicksY(availableHeight1\/36,data)).tickSize(-availableWidth,0);y2Axis.scale(y2).ticks(nv.utils.calcTicksY(availableHeight1\/36,data)).tickSize(dataBars.length?0:-availableWidth,0);g.select(".nv-focus .nv-y1.nv-axis").style("opacity",dataBars.length?1:0);g.select(".nv-focus .nv-y2.nv-axis").style("opacity",dataLines.length&&!dataLines[0].disabled?1:0).attr("transform","translate("+x.range()[1]+",0)");g.select(".nv-focus .nv-y1.nv-axis").transition().duration(transitionDuration).call(y1Axis);g.select(".nv-focus .nv-y2.nv-axis").transition().duration(transitionDuration).call(y2Axis)}onBrush()});return chart}lines.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+margin.left,e.pos[1]+margin.top];dispatch.tooltipShow(e)});lines.dispatch.on("elementMouseout.tooltip",function(e){dispatch.tooltipHide(e)});bars.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+margin.left,e.pos[1]+margin.top];dispatch.tooltipShow(e)});bars.dispatch.on("elementMouseout.tooltip",function(e){dispatch.tooltipHide(e)});dispatch.on("tooltipHide",function(){if(tooltips)nv.tooltip.cleanup()});chart.dispatch=dispatch;chart.legend=legend;chart.lines=lines;chart.lines2=lines2;chart.bars=bars;chart.bars2=bars2;chart.xAxis=xAxis;chart.x2Axis=x2Axis;chart.y1Axis=y1Axis;chart.y2Axis=y2Axis;chart.y3Axis=y3Axis;chart.y4Axis=y4Axis;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{width:{get:function(){return width},set:function(_){width=_}},height:{get:function(){return height},set:function(_){height=_}},showLegend:{get:function(){return showLegend},set:function(_){showLegend=_}},tooltips:{get:function(){return tooltips},set:function(_){tooltips=_}},tooltipContent:{get:function(){return tooltip},set:function(_){tooltip=_}},brushExtent:{get:function(){return brushExtent},set:function(_){brushExtent=_}},noData:{get:function(){return noData},set:function(_){noData=_}},focusEnable:{get:function(){return focusEnable},set:function(_){focusEnable=_}},focusHeight:{get:function(){return focusHeight},set:function(_){focusHeight=_}},focusShowAxisX:{get:function(){return focusShowAxisX},set:function(_){focusShowAxisX=_}},focusShowAxisY:{get:function(){return focusShowAxisY},set:function(_){focusShowAxisY=_}},legendLeftAxisHint:{get:function(){return legendLeftAxisHint},set:function(_){legendLeftAxisHint=_}},legendRightAxisHint:{get:function(){return legendRightAxisHint},set:function(_){legendRightAxisHint=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return transitionDuration},set:function(_){transitionDuration=_}},color:{get:function(){return color},set:function(_){color=nv.utils.getColor(_);legend.color(color)}},x:{get:function(){return getX},set:function(_){getX=_;lines.x(_);lines2.x(_);bars.x(_);bars2.x(_)}},y:{get:function(){return getY},set:function(_){getY=_;lines.y(_);lines2.y(_);bars.y(_);bars2.y(_)}}});nv.utils.inheritOptions(chart,lines);nv.utils.initOptions(chart);return chart};nv.models.lineWithFocusChart=function(){"use strict";var lines=nv.models.line(),lines2=nv.models.line(),xAxis=nv.models.axis(),yAxis=nv.models.axis(),x2Axis=nv.models.axis(),y2Axis=nv.models.axis(),legend=nv.models.legend(),brush=d3.svg.brush();var margin={top:30,right:30,bottom:30,left:60},margin2={top:0,right:30,bottom:20,left:60},color=nv.utils.defaultColor(),width=null,height=null,height2=100,x,y,x2,y2,showLegend=true,brushExtent=null,tooltips=true,tooltip=function(key,x,y,e,graph){return"

"+key+"<\/h3>"+"

"+y+" at "+x+"<\/p>"},noData="No Data Available.",dispatch=d3.dispatch("tooltipShow","tooltipHide","brush","stateChange","changeState"),transitionDuration=250,state=nv.utils.state(),defaultState=null;lines.clipEdge(true);lines2.interactive(false);xAxis.orient("bottom").tickPadding(5);yAxis.orient("left");x2Axis.orient("bottom").tickPadding(5);y2Axis.orient("left");var showTooltip=function(e,offsetElement){var left=e.pos[0]+(offsetElement.offsetLeft||0),top=e.pos[1]+(offsetElement.offsetTop||0),x=xAxis.tickFormat()(lines.x()(e.point,e.pointIndex)),y=yAxis.tickFormat()(lines.y()(e.point,e.pointIndex)),content=tooltip(e.series.key,x,y,e,chart);nv.tooltip.show([left,top],content,null,null,offsetElement)};var stateGetter=function(data){return function(){return{active:data.map(function(d){return!d.disabled})}}};var stateSetter=function(data){return function(state){if(state.active!==undefined)data.forEach(function(series,i){series.disabled=!state.active[i]})}};function chart(selection){selection.each(function(data){var container=d3.select(this),that=this;nv.utils.initSVG(container);var availableWidth=(width||parseInt(container.style("width"))||960)-margin.left-margin.right,availableHeight1=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom-height2,availableHeight2=height2-margin2.top-margin2.bottom;chart.update=function(){container.transition().duration(transitionDuration).call(chart)};chart.container=this;state.setter(stateSetter(data),chart.update).getter(stateGetter(data)).update();state.disabled=data.map(function(d){return!!d.disabled});if(!defaultState){var key;defaultState={};for(key in state){if(state[key]instanceof Array)defaultState[key]=state[key].slice(0);else defaultState[key]=state[key]}}if(!data||!data.length||!data.filter(function(d){return d.values.length}).length){var noDataText=container.selectAll(".nv-noData").data([noData]);noDataText.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle");noDataText.attr("x",margin.left+availableWidth\/2).attr("y",margin.top+availableHeight1\/2).text(function(d){return d});return chart}else{container.selectAll(".nv-noData").remove()}x=lines.xScale();y=lines.yScale();x2=lines2.xScale();y2=lines2.yScale();var wrap=container.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([data]);var gEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g");var g=wrap.select("g");gEnter.append("g").attr("class","nv-legendWrap");var focusEnter=gEnter.append("g").attr("class","nv-focus");focusEnter.append("g").attr("class","nv-x nv-axis");focusEnter.append("g").attr("class","nv-y nv-axis");focusEnter.append("g").attr("class","nv-linesWrap");var contextEnter=gEnter.append("g").attr("class","nv-context");contextEnter.append("g").attr("class","nv-x nv-axis");contextEnter.append("g").attr("class","nv-y nv-axis");contextEnter.append("g").attr("class","nv-linesWrap");contextEnter.append("g").attr("class","nv-brushBackground");contextEnter.append("g").attr("class","nv-x nv-brush");if(showLegend){legend.width(availableWidth);g.select(".nv-legendWrap").datum(data).call(legend);if(margin.top!=legend.height()){margin.top=legend.height();availableHeight1=(height||parseInt(container.style("height"))||400)-margin.top-margin.bottom-height2}g.select(".nv-legendWrap").attr("transform","translate(0,"+-margin.top+")")}wrap.attr("transform","translate("+margin.left+","+margin.top+")");lines.width(availableWidth).height(availableHeight1).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled}));lines2.defined(lines.defined()).width(availableWidth).height(availableHeight2).color(data.map(function(d,i){return d.color||color(d,i)}).filter(function(d,i){return!data[i].disabled}));g.select(".nv-context").attr("transform","translate(0,"+(availableHeight1+margin.bottom+margin2.top)+")");var contextLinesWrap=g.select(".nv-context .nv-linesWrap").datum(data.filter(function(d){return!d.disabled}));d3.transition(contextLinesWrap).call(lines2);xAxis.scale(x).ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight1,0);yAxis.scale(y).ticks(nv.utils.calcTicksY(availableHeight1\/36,data)).tickSize(-availableWidth,0);g.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+availableHeight1+")");brush.x(x2).on("brush",function(){var oldTransition=chart.duration();chart.duration(0);onBrush();chart.duration(oldTransition)});if(brushExtent)brush.extent(brushExtent);var brushBG=g.select(".nv-brushBackground").selectAll("g").data([brushExtent||brush.extent()]);var brushBGenter=brushBG.enter().append("g");brushBGenter.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",availableHeight2);brushBGenter.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",availableHeight2);var gBrush=g.select(".nv-x.nv-brush").call(brush);gBrush.selectAll("rect").attr("height",availableHeight2);gBrush.selectAll(".resize").append("path").attr("d",resizePath);onBrush();x2Axis.scale(x2).ticks(nv.utils.calcTicksX(availableWidth\/100,data)).tickSize(-availableHeight2,0);g.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y2.range()[0]+")");d3.transition(g.select(".nv-context .nv-x.nv-axis")).call(x2Axis);y2Axis.scale(y2).ticks(nv.utils.calcTicksY(availableHeight2\/36,data)).tickSize(-availableWidth,0);d3.transition(g.select(".nv-context .nv-y.nv-axis")).call(y2Axis);g.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+y2.range()[0]+")");legend.dispatch.on("stateChange",function(newState){for(var key in newState)state[key]=newState[key];dispatch.stateChange(state);chart.update()});dispatch.on("tooltipShow",function(e){if(tooltips)showTooltip(e,that.parentNode)});dispatch.on("changeState",function(e){if(typeof e.disabled!=="undefined"){data.forEach(function(series,i){series.disabled=e.disabled[i]})}chart.update()});function resizePath(d){var e=+(d=="e"),x=e?1:-1,y=availableHeight2\/3;return"M"+.5*x+","+y+"A6,6 0 0 "+e+" "+6.5*x+","+(y+6)+"V"+(2*y-6)+"A6,6 0 0 "+e+" "+.5*x+","+2*y+"Z"+"M"+2.5*x+","+(y+8)+"V"+(2*y-8)+"M"+4.5*x+","+(y+8)+"V"+(2*y-8)}function updateBrushBG(){if(!brush.empty())brush.extent(brushExtent);brushBG.data([brush.empty()?x2.domain():brushExtent]).each(function(d,i){var leftWidth=x2(d[0])-x.range()[0],rightWidth=x.range()[1]-x2(d[1]);d3.select(this).select(".left").attr("width",leftWidth<0?0:leftWidth);d3.select(this).select(".right").attr("x",x2(d[1])).attr("width",rightWidth<0?0:rightWidth)})}function onBrush(){brushExtent=brush.empty()?null:brush.extent();var extent=brush.empty()?x2.domain():brush.extent();if(Math.abs(extent[0]-extent[1])<=1){return}dispatch.brush({extent:extent,brush:brush});updateBrushBG();var focusLinesWrap=g.select(".nv-focus .nv-linesWrap").datum(data.filter(function(d){return!d.disabled}).map(function(d,i){return{key:d.key,area:d.area,values:d.values.filter(function(d,i){return lines.x()(d,i)>=extent[0]&&lines.x()(d,i)<=extent[1]})}}));focusLinesWrap.transition().duration(transitionDuration).call(lines);g.select(".nv-focus .nv-x.nv-axis").transition().duration(transitionDuration).call(xAxis);g.select(".nv-focus .nv-y.nv-axis").transition().duration(transitionDuration).call(yAxis)}});return chart}lines.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+margin.left,e.pos[1]+margin.top];dispatch.tooltipShow(e)});lines.dispatch.on("elementMouseout.tooltip",function(e){dispatch.tooltipHide(e)});dispatch.on("tooltipHide",function(){if(tooltips)nv.tooltip.cleanup()});chart.dispatch=dispatch;chart.legend=legend;chart.lines=lines;chart.lines2=lines2;chart.xAxis=xAxis;chart.yAxis=yAxis;chart.x2Axis=x2Axis;chart.y2Axis=y2Axis;chart.options=nv.utils.optionsFunc.bind(chart);$/;" m nv.addGraph phpunit/coverage/js/nv.d3.min.js /^(function(){var nv=window.nv||{};window.nv=nv;nv.dev=false;nv.tooltip=nv.tooltip||{};nv.utils=nv.utils||{};nv.models=nv.models||{};nv.charts={};nv.graphs=[];nv.logs={};nv.dispatch=d3.dispatch("render_start","render_end");if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="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=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}}if(nv.dev){nv.dispatch.on("render_start",function(e){nv.logs.startTime=+new Date});nv.dispatch.on("render_end",function(e){nv.logs.endTime=+new Date;nv.logs.totalTime=nv.logs.endTime-nv.logs.startTime;nv.log("total",nv.logs.totalTime)})}nv.log=function(){if(nv.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(nv.dev&&window.console&&typeof console.log=="function"&&Function.prototype.bind){var log=Function.prototype.bind.call(console.log,console);log.apply(console,arguments)}return arguments[arguments.length-1]};nv.deprecated=function(name){if(nv.dev&&console&&console.warn){console.warn("`"+name+"` has been deprecated.")}};nv.render=function render(step){step=step||1;nv.render.active=true;nv.dispatch.render_start();setTimeout(function(){var chart,graph;for(var i=0;iavailableWidth||mouseY>availableHeight||d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined||mouseOutAnyReason){if(isMSIE){if(d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined&&d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass)){return}}dispatch.elementMouseout({mouseX:mouseX,mouseY:mouseY});layer.renderGuideLine(null);return}var pointXValue=xScale.invert(mouseX);dispatch.elementMousemove({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue});if(d3.event.type==="dblclick"){dispatch.elementDblclick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}if(d3.event.type==="click"){dispatch.elementClick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}}svgContainer.on("mousemove",mouseHandler,true).on("mouseout",mouseHandler,true).on("dblclick",mouseHandler).on("click",mouseHandler);layer.renderGuideLine=function(x){if(!showGuideLine)return;var line=wrap.select(".nv-interactiveGuideLine").selectAll("line").data(x!=null?[nv.utils.NaNtoZero(x)]:[],String);line.enter().append("line").attr("class","nv-guideline").attr("x1",function(d){return d}).attr("x2",function(d){return d}).attr("y1",availableHeight).attr("y2",0);line.exit().remove()}})}layer.dispatch=dispatch;layer.tooltip=tooltip;layer.margin=function(_){if(!arguments.length)return margin;margin.top=typeof _.top!="undefined"?_.top:margin.top;margin.left=typeof _.left!="undefined"?_.left:margin.left;return layer};layer.width=function(_){if(!arguments.length)return width;width=_;return layer};layer.height=function(_){if(!arguments.length)return height;height=_;return layer};layer.xScale=function(_){if(!arguments.length)return xScale;xScale=_;return layer};layer.showGuideLine=function(_){if(!arguments.length)return showGuideLine;showGuideLine=_;return layer};layer.svgContainer=function(_){if(!arguments.length)return svgContainer;svgContainer=_;return layer};return layer};nv.interactiveBisect=function(values,searchVal,xAccessor){"use strict";if(!(values instanceof Array)){return null}if(typeof xAccessor!=="function"){xAccessor=function(d,i){return d.x}}var bisect=d3.bisector(xAccessor).left;var index=d3.max([0,bisect(values,searchVal)-1]);var currentValue=xAccessor(values[index],index);if(typeof currentValue==="undefined"){currentValue=index}if(currentValue===searchVal){return index}var nextIndex=d3.min([index+1,values.length-1]);var nextValue=xAccessor(values[nextIndex],nextIndex);if(typeof nextValue==="undefined"){nextValue=nextIndex}if(Math.abs(nextValue-searchVal)>=Math.abs(currentValue-searchVal)){return index}else{return nextIndex}};nv.nearestValueIndex=function(values,searchVal,threshold){"use strict";var yDistMax=Infinity,indexToHighlight=null;values.forEach(function(d,i){var delta=Math.abs(searchVal-d);if(delta<=yDistMax&&delta"+d.footer+"<\/div>";return html};var dataSeriesExists=function(d){if(d&&d.series&&d.series.length>0){return true}return false};function convertViewBoxRatio(){if(chartContainer){var svg=d3.select(chartContainer);if(svg.node().tagName!=="svg"){svg=svg.select("svg")}var viewBox=svg.node()?svg.attr("viewBox"):null;if(viewBox){viewBox=viewBox.split(" ");var ratio=parseInt(svg.style("width"))\/viewBox[2];position.left=position.left*ratio;position.top=position.top*ratio}}}function getTooltipContainer(newContent){var body;if(chartContainer){body=d3.select(chartContainer)}else{body=d3.select("body")}var container=body.select(".nvtooltip");if(container.node()===null){container=body.append("div").attr("class","nvtooltip "+(classes?classes:"xy-tooltip")).attr("id",id)}container.node().innerHTML=newContent;container.style("top",0).style("left",0).style("opacity",0);container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true);container.classed(nvPointerEventsClass,true);return container.node()}function nvtooltip(){if(!enabled)return;if(!dataSeriesExists(data))return;convertViewBoxRatio();var left=position.left;var top=fixedTop!=null?fixedTop:position.top;var container=getTooltipContainer(contentGenerator(data));tooltipElem=container;if(chartContainer){var svgComp=chartContainer.getElementsByTagName("svg")[0];var boundRect=svgComp?svgComp.getBoundingClientRect():chartContainer.getBoundingClientRect();var svgOffset={left:0,top:0};if(svgComp){var svgBound=svgComp.getBoundingClientRect();var chartBound=chartContainer.getBoundingClientRect();var svgBoundTop=svgBound.top;if(svgBoundTop<0){var containerBound=chartContainer.getBoundingClientRect();svgBoundTop=Math.abs(svgBoundTop)>containerBound.height?0:svgBoundTop}svgOffset.top=Math.abs(svgBoundTop-chartBound.top);svgOffset.left=Math.abs(svgBound.left-chartBound.left)}left+=chartContainer.offsetLeft+svgOffset.left-2*chartContainer.scrollLeft;top+=chartContainer.offsetTop+svgOffset.top-2*chartContainer.scrollTop}if(snapDistance&&snapDistance>0){top=Math.floor(top\/snapDistance)*snapDistance}nv.tooltip.calcTooltipPosition([left,top],gravity,distance,container);return nvtooltip}nvtooltip.nvPointerEventsClass=nvPointerEventsClass;nvtooltip.content=function(_){if(!arguments.length)return content;content=_;return nvtooltip};nvtooltip.tooltipElem=function(){return tooltipElem};nvtooltip.contentGenerator=function(_){if(!arguments.length)return contentGenerator;if(typeof _==="function"){contentGenerator=_}return nvtooltip};nvtooltip.data=function(_){if(!arguments.length)return data;data=_;return nvtooltip};nvtooltip.gravity=function(_){if(!arguments.length)return gravity;gravity=_;return nvtooltip};nvtooltip.distance=function(_){if(!arguments.length)return distance;distance=_;return nvtooltip};nvtooltip.snapDistance=function(_){if(!arguments.length)return snapDistance;snapDistance=_;return nvtooltip};nvtooltip.classes=function(_){if(!arguments.length)return classes;classes=_;return nvtooltip};nvtooltip.chartContainer=function(_){if(!arguments.length)return chartContainer;chartContainer=_;return nvtooltip};nvtooltip.position=function(_){if(!arguments.length)return position;position.left=typeof _.left!=="undefined"?_.left:position.left;position.top=typeof _.top!=="undefined"?_.top:position.top;return nvtooltip};nvtooltip.fixedTop=function(_){if(!arguments.length)return fixedTop;fixedTop=_;return nvtooltip};nvtooltip.enabled=function(_){if(!arguments.length)return enabled;enabled=_;return nvtooltip};nvtooltip.valueFormatter=function(_){if(!arguments.length)return valueFormatter;if(typeof _==="function"){valueFormatter=_}return nvtooltip};nvtooltip.headerFormatter=function(_){if(!arguments.length)return headerFormatter;if(typeof _==="function"){headerFormatter=_}return nvtooltip};nvtooltip.id=function(){return id};return nvtooltip};nv.tooltip.show=function(pos,content,gravity,dist,parentContainer,classes){var container=document.createElement("div");container.className="nvtooltip "+(classes?classes:"xy-tooltip");var body=parentContainer;if(!parentContainer||parentContainer.tagName.match(\/g|svg\/i)){body=document.getElementsByTagName("body")[0]}container.style.left=0;container.style.top=0;container.style.opacity=0;if(typeof content!=="string")container.appendChild(content);else container.innerHTML=content;body.appendChild(container);if(parentContainer){pos[0]=pos[0]-parentContainer.scrollLeft;pos[1]=pos[1]-parentContainer.scrollTop}nv.tooltip.calcTooltipPosition(pos,gravity,dist,container)};nv.tooltip.findFirstNonSVGParent=function(Elem){while(Elem.tagName.match(\/^g|svg$\/i)!==null){Elem=Elem.parentNode}return Elem};nv.tooltip.findTotalOffsetTop=function(Elem,initialTop){var offsetTop=initialTop;do{if(!isNaN(Elem.offsetTop)){offsetTop+=Elem.offsetTop}}while(Elem=Elem.offsetParent);return offsetTop};nv.tooltip.findTotalOffsetLeft=function(Elem,initialLeft){var offsetLeft=initialLeft;do{if(!isNaN(Elem.offsetLeft)){offsetLeft+=Elem.offsetLeft}}while(Elem=Elem.offsetParent);return offsetLeft};nv.tooltip.calcTooltipPosition=function(pos,gravity,dist,container){var height=parseInt(container.offsetHeight),width=parseInt(container.offsetWidth),windowWidth=nv.utils.windowSize().width,windowHeight=nv.utils.windowSize().height,scrollTop=window.pageYOffset,scrollLeft=window.pageXOffset,left,top;windowHeight=window.innerWidth>=document.body.scrollWidth?windowHeight:windowHeight-16;windowWidth=window.innerHeight>=document.body.scrollHeight?windowWidth:windowWidth-16;gravity=gravity||"s";dist=dist||20;var tooltipTop=function(Elem){return nv.tooltip.findTotalOffsetTop(Elem,top)};var tooltipLeft=function(Elem){return nv.tooltip.findTotalOffsetLeft(Elem,left)};switch(gravity){case"e":left=pos[0]-width-dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftscrollLeft?pos[0]+dist:scrollLeft-tLeft+left;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"w":left=pos[0]+dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeft+width>windowWidth)left=pos[0]-width-dist;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"n":left=pos[0]-width\/2-5;top=pos[1]+dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(tTop+height>scrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"s":left=pos[0]-width\/2;top=pos[1]-height-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(scrollTop>tTop)top=scrollTop;break;case"none":left=pos[0];top=pos[1]-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);break}container.style.left=left+"px";container.style.top=top+"px";container.style.opacity=1;container.style.position="absolute";return container};nv.tooltip.cleanup=function(){var tooltips=document.getElementsByClassName("nvtooltip");var purging=[];while(tooltips.length){purging.push(tooltips[0]);tooltips[0].style.transitionDelay="0 !important";tooltips[0].style.opacity=0;tooltips[0].className="nvtooltip-pending-removal"}setTimeout(function(){while(purging.length){var removeMe=purging.pop();removeMe.parentNode.removeChild(removeMe)}},500)}})();nv.utils.windowSize=function(){var size={width:640,height:480};if(document.body&&document.body.offsetWidth){size.width=document.body.offsetWidth;size.height=document.body.offsetHeight}if(document.compatMode=="CSS1Compat"&&document.documentElement&&document.documentElement.offsetWidth){size.width=document.documentElement.offsetWidth;size.height=document.documentElement.offsetHeight}if(window.innerWidth&&window.innerHeight){size.width=window.innerWidth;size.height=window.innerHeight}return size};nv.utils.windowResize=function(handler){if(window.addEventListener){window.addEventListener("resize",handler)}else{nv.log("ERROR: Failed to bind to window.resize with: ",handler)}return{callback:handler,clear:function(){window.removeEventListener("resize",handler)}}};nv.utils.getColor=function(color){if(!arguments.length){return nv.utils.defaultColor()}else if(color instanceof Array){return function(d,i){return d.color||color[i%color.length]}}else{return color}};nv.utils.defaultColor=function(){var colors=d3.scale.category20().range();return function(d,i){return d.color||colors[i%colors.length]}};nv.utils.customTheme=function(dictionary,getKey,defaultColors){getKey=getKey||function(series){return series.key};defaultColors=defaultColors||d3.scale.category20().range();var defIndex=defaultColors.length;return function(series,index){var key=getKey(series);if(typeof dictionary[key]==="function"){return dictionary[key]()}else if(dictionary[key]!==undefined){return dictionary[key]}else{if(!defIndex){defIndex=defaultColors.length}defIndex=defIndex-1;return defaultColors[defIndex]}}};nv.utils.pjax=function(links,content){var load=function(href){d3.html(href,function(fragment){var target=d3.select(content).node();target.parentNode.replaceChild(d3.select(fragment).select(content).node(),target);nv.utils.pjax(links,content)})};d3.selectAll(links).on("click",function(){history.pushState(this.href,this.textContent,this.href);load(this.href);d3.event.preventDefault()});d3.select(window).on("popstate",function(){if(d3.event.state){load(d3.event.state)}})};nv.utils.calcApproxTextWidth=function(svgTextElem){if(typeof svgTextElem.style==="function"&&typeof svgTextElem.text==="function"){var fontSize=parseInt(svgTextElem.style("font-size").replace("px",""));var textLength=svgTextElem.text().length;return textLength*fontSize*.5}return 0};nv.utils.NaNtoZero=function(n){if(typeof n!=="number"||isNaN(n)||n===null||n===Infinity||n===-Infinity){return 0}return n};d3.selection.prototype.watchTransition=function(renderWatch){var args=[this].concat([].slice.call(arguments,1));return renderWatch.transition.apply(renderWatch,args)};nv.utils.renderWatch=function(dispatch,duration){if(!(this instanceof nv.utils.renderWatch)){return new nv.utils.renderWatch(dispatch,duration)}var _duration=duration!==undefined?duration:250;var renderStack=[];var self=this;this.models=function(models){models=[].slice.call(arguments,0);models.forEach(function(model){model.__rendered=false;(function(m){m.dispatch.on("renderEnd",function(arg){m.__rendered=true;self.renderEnd("model")})})(model);if(renderStack.indexOf(model)<0){renderStack.push(model)}});return this};this.reset=function(duration){if(duration!==undefined){_duration=duration}renderStack=[]};this.transition=function(selection,args,duration){args=arguments.length>1?[].slice.call(arguments,1):[];if(args.length>1){duration=args.pop()}else{duration=_duration!==undefined?_duration:250}selection.__rendered=false;if(renderStack.indexOf(selection)<0){renderStack.push(selection)}if(duration===0){selection.__rendered=true;selection.delay=function(){return this};selection.duration=function(){return this};return selection}else{if(selection.length===0){selection.__rendered=true}else if(selection.every(function(d){return!d.length})){selection.__rendered=true}else{selection.__rendered=false}var n=0;return selection.transition().duration(duration).each(function(){++n}).each("end",function(d,i){if(--n===0){selection.__rendered=true;self.renderEnd.apply(this,args)}})}};this.renderEnd=function(){if(renderStack.every(function(d){return d.__rendered})){renderStack.forEach(function(d){d.__rendered=false});dispatch.renderEnd.apply(this,arguments)}}};nv.utils.deepExtend=function(dst){var sources=arguments.length>1?[].slice.call(arguments,1):[];sources.forEach(function(source){for(key in source){var isArray=dst[key]instanceof Array;var isObject=typeof dst[key]==="object";var srcObj=typeof source[key]==="object";if(isObject&&!isArray&&srcObj){nv.utils.deepExtend(dst[key],source[key])}else{dst[key]=source[key]}}})};nv.utils.state=function(){if(!(this instanceof nv.utils.state)){return new nv.utils.state}var state={};var _self=this;var _setState=function(){};var _getState=function(){return{}};var init=null;var changed=null;this.dispatch=d3.dispatch("change","set");this.dispatch.on("set",function(state){_setState(state,true)});this.getter=function(fn){_getState=fn;return this};this.setter=function(fn,callback){if(!callback){callback=function(){}}_setState=function(state,update){fn(state);if(update){callback()}};return this};this.init=function(state){init=init||{};nv.utils.deepExtend(init,state)};var _set=function(){var settings=_getState();if(JSON.stringify(settings)===JSON.stringify(state)){return false}for(var key in settings){if(state[key]===undefined){state[key]={}}state[key]=settings[key];changed=true}return true};this.update=function(){if(init){_setState(init,false);init=null}if(_set.call(this)){this.dispatch.change(state)}}};nv.utils.optionsFunc=function(args){nv.deprecated("nv.utils.optionsFunc");if(args){d3.map(args).forEach(function(key,value){if(typeof this[key]==="function"){this[key](value)}}.bind(this))}return this};nv.utils.calcTicksX=function(numTicks,data){var numValues=1;var i=0;for(i;inumValues?stream_len:numValues}nv.log("Requested number of ticks: ",numTicks);nv.log("Calculated max values to be: ",numValues);numTicks=numTicks>numValues?numTicks=numValues-1:numTicks;numTicks=numTicks<1?1:numTicks;numTicks=Math.floor(numTicks);nv.log("Calculating tick count as: ",numTicks);return numTicks};nv.utils.calcTicksY=function(numTicks,data){return nv.utils.calcTicksX(numTicks,data)};nv.utils.initOption=function(chart,name){if(chart._calls&&chart._calls[name]){chart[name]=chart._calls[name]}else{chart[name]=function(_){if(!arguments.length)return chart._options[name];chart._options[name]=_;return chart}}};nv.utils.initOptions=function(chart){var ops=Object.getOwnPropertyNames(chart._options||{});var calls=Object.getOwnPropertyNames(chart._calls||{});ops=ops.concat(calls);for(var i in ops){nv.utils.initOption(chart,ops[i])}};nv.utils.inheritOptionsD3=function(target,d3_source,oplist){target._d3options=oplist.concat(target._d3options||[]);oplist.unshift(d3_source);oplist.unshift(target);d3.rebind.apply(this,oplist)};nv.utils.arrayUnique=function(a){return a.sort().filter(function(item,pos){return!pos||item!=a[pos-1]})};nv.utils.symbolMap=d3.map();nv.utils.symbol=function(){var type,size=64;function symbol(d,i){var t=type.call(this,d,i);var s=size.call(this,d,i);if(d3.svg.symbolTypes.indexOf(t)!==-1){return d3.svg.symbol().type(t).size(s)()}else{return nv.utils.symbolMap.get(t)(s)}}symbol.type=function(_){if(!arguments.length)return type;type=d3.functor(_);return symbol};symbol.size=function(_){if(!arguments.length)return size;size=d3.functor(_);return symbol};return symbol};nv.utils.inheritOptions=function(target,source){var ops=Object.getOwnPropertyNames(source._options||{});var calls=Object.getOwnPropertyNames(source._calls||{});var inherited=source._inherited||[];var d3ops=source._d3options||[];var args=ops.concat(calls).concat(inherited).concat(d3ops);args.unshift(source);args.unshift(target);d3.rebind.apply(this,args);target._inherited=nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited||[]));target._d3options=nv.utils.arrayUnique(d3ops.concat(target._d3options||[]))};nv.utils.initSVG=function(svg){svg.classed({"nvd3-svg":true})};nv.models.axis=function(){"use strict";var axis=d3.svg.axis();var scale=d3.scale.linear();var margin={top:0,right:0,bottom:0,left:0},width=75,height=60,axisLabelText=null,showMaxMin=true,highlightZero=true,rotateLabels=0,rotateYLabel=true,staggerLabels=false,isOrdinal=false,ticks=null,axisLabelDistance=0,duration=250,dispatch=d3.dispatch("renderEnd"),axisRendered=false,maxMinRendered=false;axis.scale(scale).orient("bottom").tickFormat(function(d){return d});var scale0;var renderWatch=nv.utils.renderWatch(dispatch,duration);function chart(selection){renderWatch.reset();selection.each(function(data){var container=d3.select(this);nv.utils.initSVG(container);var wrap=container.selectAll("g.nv-wrap.nv-axis").data([data]);var wrapEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-axis");var gEnter=wrapEnter.append("g");var g=wrap.select("g");if(ticks!==null)axis.ticks(ticks);else if(axis.orient()=="top"||axis.orient()=="bottom")axis.ticks(Math.abs(scale.range()[1]-scale.range()[0])\/100);g.watchTransition(renderWatch,"axis").call(axis);scale0=scale0||axis.scale();var fmt=axis.tickFormat();if(fmt==null){fmt=scale0.tickFormat()}var axisLabel=g.selectAll("text.nv-axislabel").data([axisLabelText||null]);axisLabel.exit().remove();switch(axis.orient()){case"top":axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",0).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-axis.tickPadding()).attr("text-anchor","middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max top").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale.range()[i])+",0)"})}break;case"bottom":var xLabelMargin=axisLabelDistance+36;var maxTextWidth=30;var xTicks=g.selectAll("g").select("text");if(rotateLabels%360){xTicks.each(function(d,i){var width=this.getBoundingClientRect().width;if(width>maxTextWidth)maxTextWidth=width});var sin=Math.abs(Math.sin(rotateLabels*Math.PI\/180));var xLabelMargin=(sin?sin*maxTextWidth:maxTextWidth)+30;xTicks.attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels%360>0?"start":"end")}axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",xLabelMargin).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data([scale.domain()[0],scale.domain()[scale.domain().length-1]]);axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",axis.tickPadding()).attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels?rotateLabels%360>0?"start":"end":"middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max bottom").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"})}if(staggerLabels)xTicks.attr("transform",function(d,i){return"translate(0,"+(i%2==0?"0":"12")+")"});break;case"right":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"begin").attr("transform",rotateYLabel?"rotate(90)":"").attr("y",rotateYLabel?-Math.max(margin.right,width)+12:-10).attr("x",rotateYLabel?scale.range()[0]\/2:axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",axis.tickPadding()).style("text-anchor","start").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break;case"left":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"end").attr("transform",rotateYLabel?"rotate(-90)":"").attr("y",rotateYLabel?-Math.max(margin.left,width)+25-(axisLabelDistance||0):-10).attr("x",rotateYLabel?-scale.range()[0]\/2:-axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale0(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-axis.tickPadding()).attr("text-anchor","end").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break}axisLabel.text(function(d){return d});if(showMaxMin&&(axis.orient()==="left"||axis.orient()==="right")){g.selectAll("g").each(function(d,i){d3.select(this).select("text").attr("opacity",1);if(scale(d)scale.range()[0]-10){if(d>1e-10||d<-1e-10)d3.select(this).attr("opacity",0);d3.select(this).select("text").attr("opacity",0)}});if(scale.domain()[0]==scale.domain()[1]&&scale.domain()[0]==0){wrap.selectAll("g.nv-axisMaxMin").style("opacity",function(d,i){return!i?1:0})}}if(showMaxMin&&(axis.orient()==="top"||axis.orient()==="bottom")){var maxMinRange=[];wrap.selectAll("g.nv-axisMaxMin").each(function(d,i){try{if(i)maxMinRange.push(scale(d)-this.getBoundingClientRect().width-4);else maxMinRange.push(scale(d)+this.getBoundingClientRect().width+4)}catch(err){if(i)maxMinRange.push(scale(d)-4);else maxMinRange.push(scale(d)+4)}});g.selectAll("g").each(function(d,i){if(scale(d)maxMinRange[1]){if(d>1e-10||d<-1e-10)d3.select(this).remove();else d3.select(this).select("text").remove()}})}if(highlightZero){g.selectAll(".tick").filter(function(d){return!parseFloat(Math.round(this.__data__*1e5)\/1e6)&&this.__data__!==undefined}).classed("zero",true)}scale0=scale.copy()});renderWatch.renderEnd("axis immediate");return chart}chart.axis=axis;chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{axisLabelDistance:{get:function(){return axisLabelDistance},set:function(_){axisLabelDistance=_}},staggerLabels:{get:function(){return staggerLabels},set:function(_){staggerLabels=_}},rotateLabels:{get:function(){return rotateLabels},set:function(_){rotateLabels=_}},rotateYLabel:{get:function(){return rotateYLabel},set:function(_){rotateYLabel=_}},highlightZero:{get:function(){return highlightZero},set:function(_){highlightZero=_}},showMaxMin:{get:function(){return showMaxMin},set:function(_){showMaxMin=_}},axisLabel:{get:function(){return axisLabelText},set:function(_){axisLabelText=_}},height:{get:function(){return height},set:function(_){height=_}},ticks:{get:function(){return ticks},set:function(_){ticks=_}},width:{get:function(){return width},set:function(_){width=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration)}},scale:{get:function(){return scale},set:function(_){scale=_;axis.scale(scale);isOrdinal=typeof scale.rangeBands==="function";nv.utils.inheritOptionsD3(chart,scale,["domain","range","rangeBand","rangeBands"])}}});nv.utils.initOptions(chart);nv.utils.inheritOptionsD3(chart,axis,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]);$/;" f @@ -3520,6 +3524,8 @@ permissions manager/module/user.php /^ $permissions = explode( ',', str_replac permissions manager/repo/user.php /^ $permissions = implode(',', $permissions);$/;" v pers view/analytics.php /^$pers = $request->answer();$/;" v perspective js/lib/highcharts/js/highcharts-3d.src.js /^ function perspective(points, chart, insidePlotArea) {$/;" f +phone_directory manager/module/call_log.php /^ $phone_directory = array(); \/\/ Contiendra les correspondances num->Nom$/;" v +phone_log manager/module/call_log.php /^ $phone_log = array(); \/\/ Contiendra nos données$/;" v phpunitParams config/modules.json /^ "phpunitParams": {$/;" f phpunitParams manager/module/module.php /^ public static function phpunitParams($params){$/;" f phpunitPermissions config/modules.json /^ "phpunitPermissions": {$/;" f @@ -3916,8 +3922,8 @@ sociogramClass.nodeAt js/includes/sociogram.js /^sociogramClass.prototype.nodeAt sociogramClass.overload js/includes/sociogram.js /^sociogramClass.prototype.overload.nodeDirectNeighbors = function(nodeId){$/;" m sociogramClass.overload js/includes/sociogram.js /^sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){$/;" m sociogramClass.overloadGraph js/includes/sociogram.js /^sociogramClass.prototype.overloadGraph = function(){$/;" m -sortedCALL manager/module/call_log.php /^ $sortedCALL = array();$/;" v -sortedMSMS manager/module/call_log.php /^ $sortedMSMS = array();$/;" v +sortedCALL manager/module/call_log.php /^ $sortedCALL = array();$/;" v +sortedMSMS manager/module/call_log.php /^ $sortedMSMS = array();$/;" v st config/dispatcher-tree.json /^ "st" : "\/src\/static",$/;" f stop js/lib/highcharts/js/highcharts.src.js /^ };$/;" f stopForceAtlas2 js/lib/sigma/plugins/sigma-layout-forceAtlas2-min.js /^(function(undefined){"use strict";function Supervisor(sigInst,options){var _this=this,workerFn=sigInst.getForceAtlas2Worker&&sigInst.getForceAtlas2Worker();if(options=options||{},_root.URL=_root.URL||_root.webkitURL,this.sigInst=sigInst,this.graph=this.sigInst.graph,this.ppn=10,this.ppe=3,this.config={},this.shouldUseWorker=options.worker===!1?!1:!0&&webWorkers,this.workerUrl=options.workerUrl,this.started=!1,this.running=!1,this.shouldUseWorker){if(this.workerUrl)this.worker=new Worker(this.workerUrl);else{var blob=this.makeBlob(workerFn);this.worker=new Worker(URL.createObjectURL(blob))}this.worker.postMessage=this.worker.webkitPostMessage||this.worker.postMessage}else eval(workerFn);this.msgName=this.worker?"message":"newCoords",this.listener=function(t){_this.nodesByteArray=new Float32Array(t.data.nodes),_this.running&&(_this.applyLayoutChanges(),_this.sendByteArrayToWorker(),_this.sigInst.refresh())},(this.worker||document).addEventListener(this.msgName,this.listener),this.graphToByteArrays(),sigInst.bind("kill",function(){sigInst.killForceAtlas2()})}if("undefined"==typeof sigma)throw"sigma is not declared";var _root=this,webWorkers="Worker"in _root;Supervisor.prototype.makeBlob=function(t){var e;try{e=new Blob([t],{type:"application\/javascript"})}catch(s){_root.BlobBuilder=_root.BlobBuilder||_root.WebKitBlobBuilder||_root.MozBlobBuilder,e=new BlobBuilder,e.append(t),e=e.getBlob()}return e},Supervisor.prototype.graphToByteArrays=function(){var t,e,s,r=this.graph.nodes(),i=this.graph.edges(),o=r.length*this.ppn,n=i.length*this.ppe,a={};for(this.nodesByteArray=new Float32Array(o),this.edgesByteArray=new Float32Array(n),t=e=0,s=r.length;s>t;t++)a[r[t].id]=e,this.nodesByteArray[e]=r[t].x,this.nodesByteArray[e+1]=r[t].y,this.nodesByteArray[e+2]=0,this.nodesByteArray[e+3]=0,this.nodesByteArray[e+4]=0,this.nodesByteArray[e+5]=0,this.nodesByteArray[e+6]=1+this.graph.degree(r[t].id),this.nodesByteArray[e+7]=1,this.nodesByteArray[e+8]=r[t].size,this.nodesByteArray[e+9]=0,e+=this.ppn;for(t=e=0,s=i.length;s>t;t++)this.edgesByteArray[e]=a[i[t].source],this.edgesByteArray[e+1]=a[i[t].target],this.edgesByteArray[e+2]=i[t].weight||0,e+=this.ppe},Supervisor.prototype.applyLayoutChanges=function(){for(var t=this.graph.nodes(),e=0,s=0,r=this.nodesByteArray.length;r>s;s+=this.ppn)t[e].x=this.nodesByteArray[s],t[e].y=this.nodesByteArray[s+1],e++},Supervisor.prototype.sendByteArrayToWorker=function(t){var e={action:t||"loop",nodes:this.nodesByteArray.buffer},s=[this.nodesByteArray.buffer];"start"===t&&(e.config=this.config||{},e.edges=this.edgesByteArray.buffer,s.push(this.edgesByteArray.buffer)),this.shouldUseWorker?this.worker.postMessage(e,s):_root.postMessage(e,"*")},Supervisor.prototype.start=function(){if(!this.running){this.running=!0;var t,e;for(t in this.sigInst.cameras)e=this.sigInst.cameras[t],e.edgequadtree._enabled=!1;this.started?this.sendByteArrayToWorker():(this.sendByteArrayToWorker("start"),this.started=!0)}},Supervisor.prototype.stop=function(){if(this.running){var t,e,s;for(t in this.sigInst.cameras)e=this.sigInst.cameras[t],e.edgequadtree._enabled=!0,s=sigma.utils.getBoundaries(this.graph,e.readPrefix),e.settings("drawEdges")&&e.settings("enableEdgeHovering")&&e.edgequadtree.index(this.sigInst.graph,{prefix:e.readPrefix,bounds:{x:s.minX,y:s.minY,width:s.maxX-s.minX,height:s.maxY-s.minY}});this.running=!1}},Supervisor.prototype.killWorker=function(){this.worker?this.worker.terminate():(_root.postMessage({action:"kill"},"*"),document.removeEventListener(this.msgName,this.listener))},Supervisor.prototype.configure=function(t){if(this.config=t,this.started){var e={action:"config",config:this.config};this.shouldUseWorker?this.worker.postMessage(e):_root.postMessage(e,"*")}},sigma.prototype.startForceAtlas2=function(t){return this.supervisor||(this.supervisor=new Supervisor(this,t)),t&&this.supervisor.configure(t),this.supervisor.start(),this},sigma.prototype.stopForceAtlas2=function(){return this.supervisor?(this.supervisor.stop(),this):this},sigma.prototype.killForceAtlas2=function(){return this.supervisor?(this.supervisor.stop(),this.supervisor.killWorker(),this.supervisor=null,this):this},sigma.prototype.configForceAtlas2=function(t){return this.supervisor||(this.supervisor=new Supervisor(this,t)),this.supervisor.configure(t),this},sigma.prototype.isForceAtlas2Running=function(){return!!this.supervisor&&this.supervisor.running}}).call(this),function(undefined){"use strict";function no_crush(t){var e,s,r,i=["x","y","dx","dy","old_dx","old_dy","mass","convergence","size","fixed"],o=["source","target","weight"],n=["node","centerX","centerY","size","nextSibling","firstChild","mass","massCenterX","massCenterY"];for(s=0,r=n.length;r>s;s++)e=new RegExp("rp\\\\(([^,]*), '"+n[s]+"'\\\\)","g"),t=t.replace(e,0===s?"$1":"$1 + "+s);for(s=0,r=i.length;r>s;s++)e=new RegExp("np\\\\(([^,]*), '"+i[s]+"'\\\\)","g"),t=t.replace(e,0===s?"$1":"$1 + "+s);for(s=0,r=o.length;r>s;s++)e=new RegExp("ep\\\\(([^,]*), '"+o[s]+"'\\\\)","g"),t=t.replace(e,0===s?"$1":"$1 + "+s);return t}function getWorkerFn(){var t=crush?crush(Worker.toString()):Worker.toString();return";("+t+").call(this);"}var _root=this,inWebWorker=!("document"in _root),Worker=function(){function t(){var t,e,s={},r=arguments.length;for(t=r-1;t>=0;t--)for(e in arguments[t])s[e]=arguments[t][e];return s}function e(t){var e;for(e in t)"hasOwnProperty"in t&&!t.hasOwnProperty(e)||delete t[e];return t}function s(t,e,s){s=s||{};n=t,a=e,p.nodesLength=n.length,p.edgesLength=a.length,r(s)}function r(e){p.settings=t(e,p.settings)}function i(){var t,e,s,r,i,o,g,u,d,l,c,f,y,w,v;for(s=0;s=0)m=n[s]=0){if(w=Math.sqrt(Math.pow(n[s]-h[e+7],2)+Math.pow(n[s+1]-h[e+8],2)),2*h[e+3]\/w0?(v=l*n[s+6]*h[e+6]\/w\/w,n[s+2]+=c*v,n[s+3]+=f*v):0>w&&(v=-l*n[s+6]*h[e+6]\/w,n[s+2]+=c*v,n[s+3]+=f*v):w>0&&(v=l*n[s+6]*h[e+6]\/w\/w,n[s+2]+=c*v,n[s+3]+=f*v),h[e+4]<0)break;e=h[e+4];continue}e=h[e+5]}else{if(h[e]>=0&&h[e]!==s&&(c=n[s]-n[h[e]],f=n[s+1]-n[h[e]+1],w=Math.sqrt(c*c+f*f),p.settings.adjustSizes?w>0?(v=l*n[s+6]*n[h[e]+6]\/w\/w,n[s+2]+=c*v,n[s+3]+=f*v):0>w&&(v=-l*n[s+6]*n[h[e]+6]\/w,n[s+2]+=c*v,n[s+3]+=f*v):w>0&&(v=l*n[s+6]*n[h[e]+6]\/w\/w,n[s+2]+=c*v,n[s+3]+=f*v)),h[e+4]<0)break;e=h[e+4]}else for(l=p.settings.scalingRatio,r=0;ri;i+=p.ppn)c=n[r]-n[i],f=n[r+1]-n[i+1],p.settings.adjustSizes?(w=Math.sqrt(c*c+f*f)-n[r+8]-n[i+8],w>0?(v=l*n[r+6]*n[i+6]\/w\/w,n[r+2]+=c*v,n[r+3]+=f*v,n[i+2]+=c*v,n[i+3]+=f*v):0>w&&(v=100*l*n[r+6]*n[i+6],n[r+2]+=c*v,n[r+3]+=f*v,n[i+2]-=c*v,n[i+3]-=f*v)):(w=Math.sqrt(c*c+f*f),w>0&&(v=l*n[r+6]*n[i+6]\/w\/w,n[r+2]+=c*v,n[r+3]+=f*v,n[i+2]-=c*v,n[i+3]-=f*v));for(u=p.settings.gravity\/p.settings.scalingRatio,l=p.settings.scalingRatio,s=0;s0&&(v=l*n[s+6]*u):w>0&&(v=l*n[s+6]*u\/w),n[s+2]-=c*v,n[s+3]-=f*v;for(l=1*(p.settings.outboundAttractionDistribution?d:1),o=0;o0&&(v=-l*y*Math.log(1+w)\/w\/n[r+6]):w>0&&(v=-l*y*Math.log(1+w)\/w):p.settings.outboundAttractionDistribution?w>0&&(v=-l*y\/n[r+6]):w>0&&(v=-l*y)):(w=Math.sqrt(Math.pow(c,2)+Math.pow(f,2)),p.settings.linLogMode?p.settings.outboundAttractionDistribution?w>0&&(v=-l*y*Math.log(1+w)\/w\/n[r+6]):w>0&&(v=-l*y*Math.log(1+w)\/w):p.settings.outboundAttractionDistribution?(w=1,v=-l*y\/n[r+6]):(w=1,v=-l*y)),w>0&&(n[r+2]+=c*v,n[r+3]+=f*v,n[i+2]-=c*v,n[i+3]-=f*v);var W,L,F,_;if(p.settings.adjustSizes)for(s=0;sp.maxForce&&(n[s+2]=n[s+2]*p.maxForce\/W,n[s+3]=n[s+3]*p.maxForce\/W),L=n[s+6]*Math.sqrt((n[s+4]-n[s+2])*(n[s+4]-n[s+2])+(n[s+5]-n[s+3])*(n[s+5]-n[s+3])),F=Math.sqrt((n[s+4]+n[s+2])*(n[s+4]+n[s+2])+(n[s+5]+n[s+3])*(n[s+5]+n[s+3]))\/2,_=.1*Math.log(1+F)\/(1+Math.sqrt(L)),n[s]=n[s]+n[s+2]*(_\/p.settings.slowDown),n[s+1]=n[s+1]+n[s+3]*(_\/p.settings.slowDown));else for(s=0;se;e++)i();g()}var n,a,h,g,p={ppn:10,ppe:3,ppr:9,maxForce:10,iterations:0,converged:!1,settings:{linLogMode:!1,outboundAttractionDistribution:!1,adjustSizes:!1,edgeWeightInfluence:0,scalingRatio:1,strongGravityMode:!1,gravity:1,slowDown:1,barnesHutOptimize:!1,barnesHutTheta:.5,startingIterations:1,iterationsPerRender:1}};g="undefined"!=typeof window&&window.document?function(){var t;document.createEvent?(t=document.createEvent("Event"),t.initEvent("newCoords",!0,!1)):(t=document.createEventObject(),t.eventType="newCoords"),t.eventName="newCoords",t.data={nodes:n.buffer},requestAnimationFrame(function(){document.dispatchEvent(t)})}:function(){self.postMessage({nodes:n.buffer},[n.buffer])};var u=function(t){switch(t.data.action){case"start":s(new Float32Array(t.data.nodes),new Float32Array(t.data.edges),t.data.config),o(p.settings.startingIterations);break;case"loop":n=new Float32Array(t.data.nodes),o(p.settings.iterationsPerRender);break;case"config":r(t.data.config);break;case"kill":e(p),n=null,a=null,h=null,self.removeEventListener("message",u)}};self.addEventListener("message",u)},crush=null;if(inWebWorker)eval(getWorkerFn());else{if("undefined"==typeof sigma)throw"sigma is not declared";sigma.prototype.getForceAtlas2Worker=getWorkerFn}}.call(this);/;" m @@ -4240,8 +4246,8 @@ this.setter phpunit/coverage/js/nv.d3.min.js /^(function(){var nv=window.nv||{}; this.transition phpunit/coverage/js/nv.d3.min.js /^(function(){var nv=window.nv||{};window.nv=nv;nv.dev=false;nv.tooltip=nv.tooltip||{};nv.utils=nv.utils||{};nv.models=nv.models||{};nv.charts={};nv.graphs=[];nv.logs={};nv.dispatch=d3.dispatch("render_start","render_end");if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="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=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}}if(nv.dev){nv.dispatch.on("render_start",function(e){nv.logs.startTime=+new Date});nv.dispatch.on("render_end",function(e){nv.logs.endTime=+new Date;nv.logs.totalTime=nv.logs.endTime-nv.logs.startTime;nv.log("total",nv.logs.totalTime)})}nv.log=function(){if(nv.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(nv.dev&&window.console&&typeof console.log=="function"&&Function.prototype.bind){var log=Function.prototype.bind.call(console.log,console);log.apply(console,arguments)}return arguments[arguments.length-1]};nv.deprecated=function(name){if(nv.dev&&console&&console.warn){console.warn("`"+name+"` has been deprecated.")}};nv.render=function render(step){step=step||1;nv.render.active=true;nv.dispatch.render_start();setTimeout(function(){var chart,graph;for(var i=0;iavailableWidth||mouseY>availableHeight||d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined||mouseOutAnyReason){if(isMSIE){if(d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined&&d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass)){return}}dispatch.elementMouseout({mouseX:mouseX,mouseY:mouseY});layer.renderGuideLine(null);return}var pointXValue=xScale.invert(mouseX);dispatch.elementMousemove({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue});if(d3.event.type==="dblclick"){dispatch.elementDblclick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}if(d3.event.type==="click"){dispatch.elementClick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}}svgContainer.on("mousemove",mouseHandler,true).on("mouseout",mouseHandler,true).on("dblclick",mouseHandler).on("click",mouseHandler);layer.renderGuideLine=function(x){if(!showGuideLine)return;var line=wrap.select(".nv-interactiveGuideLine").selectAll("line").data(x!=null?[nv.utils.NaNtoZero(x)]:[],String);line.enter().append("line").attr("class","nv-guideline").attr("x1",function(d){return d}).attr("x2",function(d){return d}).attr("y1",availableHeight).attr("y2",0);line.exit().remove()}})}layer.dispatch=dispatch;layer.tooltip=tooltip;layer.margin=function(_){if(!arguments.length)return margin;margin.top=typeof _.top!="undefined"?_.top:margin.top;margin.left=typeof _.left!="undefined"?_.left:margin.left;return layer};layer.width=function(_){if(!arguments.length)return width;width=_;return layer};layer.height=function(_){if(!arguments.length)return height;height=_;return layer};layer.xScale=function(_){if(!arguments.length)return xScale;xScale=_;return layer};layer.showGuideLine=function(_){if(!arguments.length)return showGuideLine;showGuideLine=_;return layer};layer.svgContainer=function(_){if(!arguments.length)return svgContainer;svgContainer=_;return layer};return layer};nv.interactiveBisect=function(values,searchVal,xAccessor){"use strict";if(!(values instanceof Array)){return null}if(typeof xAccessor!=="function"){xAccessor=function(d,i){return d.x}}var bisect=d3.bisector(xAccessor).left;var index=d3.max([0,bisect(values,searchVal)-1]);var currentValue=xAccessor(values[index],index);if(typeof currentValue==="undefined"){currentValue=index}if(currentValue===searchVal){return index}var nextIndex=d3.min([index+1,values.length-1]);var nextValue=xAccessor(values[nextIndex],nextIndex);if(typeof nextValue==="undefined"){nextValue=nextIndex}if(Math.abs(nextValue-searchVal)>=Math.abs(currentValue-searchVal)){return index}else{return nextIndex}};nv.nearestValueIndex=function(values,searchVal,threshold){"use strict";var yDistMax=Infinity,indexToHighlight=null;values.forEach(function(d,i){var delta=Math.abs(searchVal-d);if(delta<=yDistMax&&delta"+d.footer+"<\/div>";return html};var dataSeriesExists=function(d){if(d&&d.series&&d.series.length>0){return true}return false};function convertViewBoxRatio(){if(chartContainer){var svg=d3.select(chartContainer);if(svg.node().tagName!=="svg"){svg=svg.select("svg")}var viewBox=svg.node()?svg.attr("viewBox"):null;if(viewBox){viewBox=viewBox.split(" ");var ratio=parseInt(svg.style("width"))\/viewBox[2];position.left=position.left*ratio;position.top=position.top*ratio}}}function getTooltipContainer(newContent){var body;if(chartContainer){body=d3.select(chartContainer)}else{body=d3.select("body")}var container=body.select(".nvtooltip");if(container.node()===null){container=body.append("div").attr("class","nvtooltip "+(classes?classes:"xy-tooltip")).attr("id",id)}container.node().innerHTML=newContent;container.style("top",0).style("left",0).style("opacity",0);container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true);container.classed(nvPointerEventsClass,true);return container.node()}function nvtooltip(){if(!enabled)return;if(!dataSeriesExists(data))return;convertViewBoxRatio();var left=position.left;var top=fixedTop!=null?fixedTop:position.top;var container=getTooltipContainer(contentGenerator(data));tooltipElem=container;if(chartContainer){var svgComp=chartContainer.getElementsByTagName("svg")[0];var boundRect=svgComp?svgComp.getBoundingClientRect():chartContainer.getBoundingClientRect();var svgOffset={left:0,top:0};if(svgComp){var svgBound=svgComp.getBoundingClientRect();var chartBound=chartContainer.getBoundingClientRect();var svgBoundTop=svgBound.top;if(svgBoundTop<0){var containerBound=chartContainer.getBoundingClientRect();svgBoundTop=Math.abs(svgBoundTop)>containerBound.height?0:svgBoundTop}svgOffset.top=Math.abs(svgBoundTop-chartBound.top);svgOffset.left=Math.abs(svgBound.left-chartBound.left)}left+=chartContainer.offsetLeft+svgOffset.left-2*chartContainer.scrollLeft;top+=chartContainer.offsetTop+svgOffset.top-2*chartContainer.scrollTop}if(snapDistance&&snapDistance>0){top=Math.floor(top\/snapDistance)*snapDistance}nv.tooltip.calcTooltipPosition([left,top],gravity,distance,container);return nvtooltip}nvtooltip.nvPointerEventsClass=nvPointerEventsClass;nvtooltip.content=function(_){if(!arguments.length)return content;content=_;return nvtooltip};nvtooltip.tooltipElem=function(){return tooltipElem};nvtooltip.contentGenerator=function(_){if(!arguments.length)return contentGenerator;if(typeof _==="function"){contentGenerator=_}return nvtooltip};nvtooltip.data=function(_){if(!arguments.length)return data;data=_;return nvtooltip};nvtooltip.gravity=function(_){if(!arguments.length)return gravity;gravity=_;return nvtooltip};nvtooltip.distance=function(_){if(!arguments.length)return distance;distance=_;return nvtooltip};nvtooltip.snapDistance=function(_){if(!arguments.length)return snapDistance;snapDistance=_;return nvtooltip};nvtooltip.classes=function(_){if(!arguments.length)return classes;classes=_;return nvtooltip};nvtooltip.chartContainer=function(_){if(!arguments.length)return chartContainer;chartContainer=_;return nvtooltip};nvtooltip.position=function(_){if(!arguments.length)return position;position.left=typeof _.left!=="undefined"?_.left:position.left;position.top=typeof _.top!=="undefined"?_.top:position.top;return nvtooltip};nvtooltip.fixedTop=function(_){if(!arguments.length)return fixedTop;fixedTop=_;return nvtooltip};nvtooltip.enabled=function(_){if(!arguments.length)return enabled;enabled=_;return nvtooltip};nvtooltip.valueFormatter=function(_){if(!arguments.length)return valueFormatter;if(typeof _==="function"){valueFormatter=_}return nvtooltip};nvtooltip.headerFormatter=function(_){if(!arguments.length)return headerFormatter;if(typeof _==="function"){headerFormatter=_}return nvtooltip};nvtooltip.id=function(){return id};return nvtooltip};nv.tooltip.show=function(pos,content,gravity,dist,parentContainer,classes){var container=document.createElement("div");container.className="nvtooltip "+(classes?classes:"xy-tooltip");var body=parentContainer;if(!parentContainer||parentContainer.tagName.match(\/g|svg\/i)){body=document.getElementsByTagName("body")[0]}container.style.left=0;container.style.top=0;container.style.opacity=0;if(typeof content!=="string")container.appendChild(content);else container.innerHTML=content;body.appendChild(container);if(parentContainer){pos[0]=pos[0]-parentContainer.scrollLeft;pos[1]=pos[1]-parentContainer.scrollTop}nv.tooltip.calcTooltipPosition(pos,gravity,dist,container)};nv.tooltip.findFirstNonSVGParent=function(Elem){while(Elem.tagName.match(\/^g|svg$\/i)!==null){Elem=Elem.parentNode}return Elem};nv.tooltip.findTotalOffsetTop=function(Elem,initialTop){var offsetTop=initialTop;do{if(!isNaN(Elem.offsetTop)){offsetTop+=Elem.offsetTop}}while(Elem=Elem.offsetParent);return offsetTop};nv.tooltip.findTotalOffsetLeft=function(Elem,initialLeft){var offsetLeft=initialLeft;do{if(!isNaN(Elem.offsetLeft)){offsetLeft+=Elem.offsetLeft}}while(Elem=Elem.offsetParent);return offsetLeft};nv.tooltip.calcTooltipPosition=function(pos,gravity,dist,container){var height=parseInt(container.offsetHeight),width=parseInt(container.offsetWidth),windowWidth=nv.utils.windowSize().width,windowHeight=nv.utils.windowSize().height,scrollTop=window.pageYOffset,scrollLeft=window.pageXOffset,left,top;windowHeight=window.innerWidth>=document.body.scrollWidth?windowHeight:windowHeight-16;windowWidth=window.innerHeight>=document.body.scrollHeight?windowWidth:windowWidth-16;gravity=gravity||"s";dist=dist||20;var tooltipTop=function(Elem){return nv.tooltip.findTotalOffsetTop(Elem,top)};var tooltipLeft=function(Elem){return nv.tooltip.findTotalOffsetLeft(Elem,left)};switch(gravity){case"e":left=pos[0]-width-dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftscrollLeft?pos[0]+dist:scrollLeft-tLeft+left;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"w":left=pos[0]+dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeft+width>windowWidth)left=pos[0]-width-dist;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"n":left=pos[0]-width\/2-5;top=pos[1]+dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(tTop+height>scrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"s":left=pos[0]-width\/2;top=pos[1]-height-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(scrollTop>tTop)top=scrollTop;break;case"none":left=pos[0];top=pos[1]-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);break}container.style.left=left+"px";container.style.top=top+"px";container.style.opacity=1;container.style.position="absolute";return container};nv.tooltip.cleanup=function(){var tooltips=document.getElementsByClassName("nvtooltip");var purging=[];while(tooltips.length){purging.push(tooltips[0]);tooltips[0].style.transitionDelay="0 !important";tooltips[0].style.opacity=0;tooltips[0].className="nvtooltip-pending-removal"}setTimeout(function(){while(purging.length){var removeMe=purging.pop();removeMe.parentNode.removeChild(removeMe)}},500)}})();nv.utils.windowSize=function(){var size={width:640,height:480};if(document.body&&document.body.offsetWidth){size.width=document.body.offsetWidth;size.height=document.body.offsetHeight}if(document.compatMode=="CSS1Compat"&&document.documentElement&&document.documentElement.offsetWidth){size.width=document.documentElement.offsetWidth;size.height=document.documentElement.offsetHeight}if(window.innerWidth&&window.innerHeight){size.width=window.innerWidth;size.height=window.innerHeight}return size};nv.utils.windowResize=function(handler){if(window.addEventListener){window.addEventListener("resize",handler)}else{nv.log("ERROR: Failed to bind to window.resize with: ",handler)}return{callback:handler,clear:function(){window.removeEventListener("resize",handler)}}};nv.utils.getColor=function(color){if(!arguments.length){return nv.utils.defaultColor()}else if(color instanceof Array){return function(d,i){return d.color||color[i%color.length]}}else{return color}};nv.utils.defaultColor=function(){var colors=d3.scale.category20().range();return function(d,i){return d.color||colors[i%colors.length]}};nv.utils.customTheme=function(dictionary,getKey,defaultColors){getKey=getKey||function(series){return series.key};defaultColors=defaultColors||d3.scale.category20().range();var defIndex=defaultColors.length;return function(series,index){var key=getKey(series);if(typeof dictionary[key]==="function"){return dictionary[key]()}else if(dictionary[key]!==undefined){return dictionary[key]}else{if(!defIndex){defIndex=defaultColors.length}defIndex=defIndex-1;return defaultColors[defIndex]}}};nv.utils.pjax=function(links,content){var load=function(href){d3.html(href,function(fragment){var target=d3.select(content).node();target.parentNode.replaceChild(d3.select(fragment).select(content).node(),target);nv.utils.pjax(links,content)})};d3.selectAll(links).on("click",function(){history.pushState(this.href,this.textContent,this.href);load(this.href);d3.event.preventDefault()});d3.select(window).on("popstate",function(){if(d3.event.state){load(d3.event.state)}})};nv.utils.calcApproxTextWidth=function(svgTextElem){if(typeof svgTextElem.style==="function"&&typeof svgTextElem.text==="function"){var fontSize=parseInt(svgTextElem.style("font-size").replace("px",""));var textLength=svgTextElem.text().length;return textLength*fontSize*.5}return 0};nv.utils.NaNtoZero=function(n){if(typeof n!=="number"||isNaN(n)||n===null||n===Infinity||n===-Infinity){return 0}return n};d3.selection.prototype.watchTransition=function(renderWatch){var args=[this].concat([].slice.call(arguments,1));return renderWatch.transition.apply(renderWatch,args)};nv.utils.renderWatch=function(dispatch,duration){if(!(this instanceof nv.utils.renderWatch)){return new nv.utils.renderWatch(dispatch,duration)}var _duration=duration!==undefined?duration:250;var renderStack=[];var self=this;this.models=function(models){models=[].slice.call(arguments,0);models.forEach(function(model){model.__rendered=false;(function(m){m.dispatch.on("renderEnd",function(arg){m.__rendered=true;self.renderEnd("model")})})(model);if(renderStack.indexOf(model)<0){renderStack.push(model)}});return this};this.reset=function(duration){if(duration!==undefined){_duration=duration}renderStack=[]};this.transition=function(selection,args,duration){args=arguments.length>1?[].slice.call(arguments,1):[];if(args.length>1){duration=args.pop()}else{duration=_duration!==undefined?_duration:250}selection.__rendered=false;if(renderStack.indexOf(selection)<0){renderStack.push(selection)}if(duration===0){selection.__rendered=true;selection.delay=function(){return this};selection.duration=function(){return this};return selection}else{if(selection.length===0){selection.__rendered=true}else if(selection.every(function(d){return!d.length})){selection.__rendered=true}else{selection.__rendered=false}var n=0;return selection.transition().duration(duration).each(function(){++n}).each("end",function(d,i){if(--n===0){selection.__rendered=true;self.renderEnd.apply(this,args)}})}};this.renderEnd=function(){if(renderStack.every(function(d){return d.__rendered})){renderStack.forEach(function(d){d.__rendered=false});dispatch.renderEnd.apply(this,arguments)}}};nv.utils.deepExtend=function(dst){var sources=arguments.length>1?[].slice.call(arguments,1):[];sources.forEach(function(source){for(key in source){var isArray=dst[key]instanceof Array;var isObject=typeof dst[key]==="object";var srcObj=typeof source[key]==="object";if(isObject&&!isArray&&srcObj){nv.utils.deepExtend(dst[key],source[key])}else{dst[key]=source[key]}}})};nv.utils.state=function(){if(!(this instanceof nv.utils.state)){return new nv.utils.state}var state={};var _self=this;var _setState=function(){};var _getState=function(){return{}};var init=null;var changed=null;this.dispatch=d3.dispatch("change","set");this.dispatch.on("set",function(state){_setState(state,true)});this.getter=function(fn){_getState=fn;return this};this.setter=function(fn,callback){if(!callback){callback=function(){}}_setState=function(state,update){fn(state);if(update){callback()}};return this};this.init=function(state){init=init||{};nv.utils.deepExtend(init,state)};var _set=function(){var settings=_getState();if(JSON.stringify(settings)===JSON.stringify(state)){return false}for(var key in settings){if(state[key]===undefined){state[key]={}}state[key]=settings[key];changed=true}return true};this.update=function(){if(init){_setState(init,false);init=null}if(_set.call(this)){this.dispatch.change(state)}}};nv.utils.optionsFunc=function(args){nv.deprecated("nv.utils.optionsFunc");if(args){d3.map(args).forEach(function(key,value){if(typeof this[key]==="function"){this[key](value)}}.bind(this))}return this};nv.utils.calcTicksX=function(numTicks,data){var numValues=1;var i=0;for(i;inumValues?stream_len:numValues}nv.log("Requested number of ticks: ",numTicks);nv.log("Calculated max values to be: ",numValues);numTicks=numTicks>numValues?numTicks=numValues-1:numTicks;numTicks=numTicks<1?1:numTicks;numTicks=Math.floor(numTicks);nv.log("Calculating tick count as: ",numTicks);return numTicks};nv.utils.calcTicksY=function(numTicks,data){return nv.utils.calcTicksX(numTicks,data)};nv.utils.initOption=function(chart,name){if(chart._calls&&chart._calls[name]){chart[name]=chart._calls[name]}else{chart[name]=function(_){if(!arguments.length)return chart._options[name];chart._options[name]=_;return chart}}};nv.utils.initOptions=function(chart){var ops=Object.getOwnPropertyNames(chart._options||{});var calls=Object.getOwnPropertyNames(chart._calls||{});ops=ops.concat(calls);for(var i in ops){nv.utils.initOption(chart,ops[i])}};nv.utils.inheritOptionsD3=function(target,d3_source,oplist){target._d3options=oplist.concat(target._d3options||[]);oplist.unshift(d3_source);oplist.unshift(target);d3.rebind.apply(this,oplist)};nv.utils.arrayUnique=function(a){return a.sort().filter(function(item,pos){return!pos||item!=a[pos-1]})};nv.utils.symbolMap=d3.map();nv.utils.symbol=function(){var type,size=64;function symbol(d,i){var t=type.call(this,d,i);var s=size.call(this,d,i);if(d3.svg.symbolTypes.indexOf(t)!==-1){return d3.svg.symbol().type(t).size(s)()}else{return nv.utils.symbolMap.get(t)(s)}}symbol.type=function(_){if(!arguments.length)return type;type=d3.functor(_);return symbol};symbol.size=function(_){if(!arguments.length)return size;size=d3.functor(_);return symbol};return symbol};nv.utils.inheritOptions=function(target,source){var ops=Object.getOwnPropertyNames(source._options||{});var calls=Object.getOwnPropertyNames(source._calls||{});var inherited=source._inherited||[];var d3ops=source._d3options||[];var args=ops.concat(calls).concat(inherited).concat(d3ops);args.unshift(source);args.unshift(target);d3.rebind.apply(this,args);target._inherited=nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited||[]));target._d3options=nv.utils.arrayUnique(d3ops.concat(target._d3options||[]))};nv.utils.initSVG=function(svg){svg.classed({"nvd3-svg":true})};nv.models.axis=function(){"use strict";var axis=d3.svg.axis();var scale=d3.scale.linear();var margin={top:0,right:0,bottom:0,left:0},width=75,height=60,axisLabelText=null,showMaxMin=true,highlightZero=true,rotateLabels=0,rotateYLabel=true,staggerLabels=false,isOrdinal=false,ticks=null,axisLabelDistance=0,duration=250,dispatch=d3.dispatch("renderEnd"),axisRendered=false,maxMinRendered=false;axis.scale(scale).orient("bottom").tickFormat(function(d){return d});var scale0;var renderWatch=nv.utils.renderWatch(dispatch,duration);function chart(selection){renderWatch.reset();selection.each(function(data){var container=d3.select(this);nv.utils.initSVG(container);var wrap=container.selectAll("g.nv-wrap.nv-axis").data([data]);var wrapEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-axis");var gEnter=wrapEnter.append("g");var g=wrap.select("g");if(ticks!==null)axis.ticks(ticks);else if(axis.orient()=="top"||axis.orient()=="bottom")axis.ticks(Math.abs(scale.range()[1]-scale.range()[0])\/100);g.watchTransition(renderWatch,"axis").call(axis);scale0=scale0||axis.scale();var fmt=axis.tickFormat();if(fmt==null){fmt=scale0.tickFormat()}var axisLabel=g.selectAll("text.nv-axislabel").data([axisLabelText||null]);axisLabel.exit().remove();switch(axis.orient()){case"top":axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",0).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-axis.tickPadding()).attr("text-anchor","middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max top").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale.range()[i])+",0)"})}break;case"bottom":var xLabelMargin=axisLabelDistance+36;var maxTextWidth=30;var xTicks=g.selectAll("g").select("text");if(rotateLabels%360){xTicks.each(function(d,i){var width=this.getBoundingClientRect().width;if(width>maxTextWidth)maxTextWidth=width});var sin=Math.abs(Math.sin(rotateLabels*Math.PI\/180));var xLabelMargin=(sin?sin*maxTextWidth:maxTextWidth)+30;xTicks.attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels%360>0?"start":"end")}axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",xLabelMargin).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data([scale.domain()[0],scale.domain()[scale.domain().length-1]]);axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",axis.tickPadding()).attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels?rotateLabels%360>0?"start":"end":"middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max bottom").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"})}if(staggerLabels)xTicks.attr("transform",function(d,i){return"translate(0,"+(i%2==0?"0":"12")+")"});break;case"right":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"begin").attr("transform",rotateYLabel?"rotate(90)":"").attr("y",rotateYLabel?-Math.max(margin.right,width)+12:-10).attr("x",rotateYLabel?scale.range()[0]\/2:axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",axis.tickPadding()).style("text-anchor","start").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break;case"left":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"end").attr("transform",rotateYLabel?"rotate(-90)":"").attr("y",rotateYLabel?-Math.max(margin.left,width)+25-(axisLabelDistance||0):-10).attr("x",rotateYLabel?-scale.range()[0]\/2:-axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale0(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-axis.tickPadding()).attr("text-anchor","end").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break}axisLabel.text(function(d){return d});if(showMaxMin&&(axis.orient()==="left"||axis.orient()==="right")){g.selectAll("g").each(function(d,i){d3.select(this).select("text").attr("opacity",1);if(scale(d)scale.range()[0]-10){if(d>1e-10||d<-1e-10)d3.select(this).attr("opacity",0);d3.select(this).select("text").attr("opacity",0)}});if(scale.domain()[0]==scale.domain()[1]&&scale.domain()[0]==0){wrap.selectAll("g.nv-axisMaxMin").style("opacity",function(d,i){return!i?1:0})}}if(showMaxMin&&(axis.orient()==="top"||axis.orient()==="bottom")){var maxMinRange=[];wrap.selectAll("g.nv-axisMaxMin").each(function(d,i){try{if(i)maxMinRange.push(scale(d)-this.getBoundingClientRect().width-4);else maxMinRange.push(scale(d)+this.getBoundingClientRect().width+4)}catch(err){if(i)maxMinRange.push(scale(d)-4);else maxMinRange.push(scale(d)+4)}});g.selectAll("g").each(function(d,i){if(scale(d)maxMinRange[1]){if(d>1e-10||d<-1e-10)d3.select(this).remove();else d3.select(this).select("text").remove()}})}if(highlightZero){g.selectAll(".tick").filter(function(d){return!parseFloat(Math.round(this.__data__*1e5)\/1e6)&&this.__data__!==undefined}).classed("zero",true)}scale0=scale.copy()});renderWatch.renderEnd("axis immediate");return chart}chart.axis=axis;chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{axisLabelDistance:{get:function(){return axisLabelDistance},set:function(_){axisLabelDistance=_}},staggerLabels:{get:function(){return staggerLabels},set:function(_){staggerLabels=_}},rotateLabels:{get:function(){return rotateLabels},set:function(_){rotateLabels=_}},rotateYLabel:{get:function(){return rotateYLabel},set:function(_){rotateYLabel=_}},highlightZero:{get:function(){return highlightZero},set:function(_){highlightZero=_}},showMaxMin:{get:function(){return showMaxMin},set:function(_){showMaxMin=_}},axisLabel:{get:function(){return axisLabelText},set:function(_){axisLabelText=_}},height:{get:function(){return height},set:function(_){height=_}},ticks:{get:function(){return ticks},set:function(_){ticks=_}},width:{get:function(){return width},set:function(_){width=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration)}},scale:{get:function(){return scale},set:function(_){scale=_;axis.scale(scale);isOrdinal=typeof scale.rangeBands==="function";nv.utils.inheritOptionsD3(chart,scale,["domain","range","rangeBand","rangeBands"])}}});nv.utils.initOptions(chart);nv.utils.inheritOptionsD3(chart,axis,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]);$/;" m this.xhr js/lib/page-manager.js /^ this.xhr[index].onreadystatechange = function(){$/;" m time manager/Database.php /^ $time = strtotime($date); \/\/ timestamp$/;" v -tmp manager/module/call_log.php /^ $tmp = $call;$/;" v -tmp manager/module/call_log.php /^ $tmp = $msms;$/;" v +tmp manager/module/call_log.php /^ $tmp = $call;$/;" v +tmp manager/module/call_log.php /^ $tmp = $msms;$/;" v toDot js/lib/highcharts/api/js/ref.js /^function toDot (id){$/;" f toHex js/lib/highcharts/js/modules/canvas-tools.js /^this.g>255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b="0"+b);a.length==1&&(a="0"+a);d.length==1&&(d="0"+d);return"#"+b+a+d};this.getHelpXML=function(){for(var b=[],c=0;cfetch() === false;$/;" v unserialize config/modules.json /^ "unserialize": {$/;" f unserialize manager/module/call_log.php /^ public static function unserialize($params){$/;" f +unserializeOld manager/module/call_log.php /^ private static function unserializeOld($params){$/;" f update.enter phpunit/coverage/js/d3.min.js /^!function(){var d3={version:"3.5.5"};var d3_arraySlice=[].slice,d3_array=function(list){return d3_arraySlice.call(list)};var d3_document=this.document;function d3_documentElement(node){return node&&(node.ownerDocument||node.document||node).documentElement}function d3_window(node){return node&&(node.ownerDocument&&node.ownerDocument.defaultView||node.document&&node||node.defaultView)}if(d3_document){try{d3_array(d3_document.documentElement.childNodes)[0].nodeType}catch(e){d3_array=function(list){var i=list.length,array=new Array(i);while(i--)array[i]=list[i];return array}}}if(!Date.now)Date.now=function(){return+new Date};if(d3_document){try{d3_document.createElement("DIV").style.setProperty("opacity",0,"")}catch(error){var d3_element_prototype=this.Element.prototype,d3_element_setAttribute=d3_element_prototype.setAttribute,d3_element_setAttributeNS=d3_element_prototype.setAttributeNS,d3_style_prototype=this.CSSStyleDeclaration.prototype,d3_style_setProperty=d3_style_prototype.setProperty;d3_element_prototype.setAttribute=function(name,value){d3_element_setAttribute.call(this,name,value+"")};d3_element_prototype.setAttributeNS=function(space,local,value){d3_element_setAttributeNS.call(this,space,local,value+"")};d3_style_prototype.setProperty=function(name,value,priority){d3_style_setProperty.call(this,name,value+"",priority)}}}d3.ascending=d3_ascending;function d3_ascending(a,b){return ab?1:a>=b?0:NaN}d3.descending=function(a,b){return ba?1:b>=a?0:NaN};d3.min=function(array,f){var i=-1,n=array.length,a,b;if(arguments.length===1){while(++i=b){a=b;break}while(++ib)a=b}else{while(++i=b){a=b;break}while(++ib)a=b}return a};d3.max=function(array,f){var i=-1,n=array.length,a,b;if(arguments.length===1){while(++i=b){a=b;break}while(++ia)a=b}else{while(++i=b){a=b;break}while(++ia)a=b}return a};d3.extent=function(array,f){var i=-1,n=array.length,a,b,c;if(arguments.length===1){while(++i=b){a=c=b;break}while(++ib)a=b;if(c=b){a=c=b;break}while(++ib)a=b;if(c1)return s\/(j-1)};d3.deviation=function(){var v=d3.variance.apply(this,arguments);return v?Math.sqrt(v):v};function d3_bisector(compare){return{left:function(a,x,lo,hi){if(arguments.length<3)lo=0;if(arguments.length<4)hi=a.length;while(lo>>1;if(compare(a[mid],x)<0)lo=mid+1;else hi=mid}return lo},right:function(a,x,lo,hi){if(arguments.length<3)lo=0;if(arguments.length<4)hi=a.length;while(lo>>1;if(compare(a[mid],x)>0)hi=mid;else lo=mid+1}return lo}}}var d3_bisect=d3_bisector(d3_ascending);d3.bisectLeft=d3_bisect.left;d3.bisect=d3.bisectRight=d3_bisect.right;d3.bisector=function(f){return d3_bisector(f.length===1?function(d,x){return d3_ascending(f(d),x)}:f)};d3.shuffle=function(array,i0,i1){if((m=arguments.length)<3){i1=array.length;if(m<2)i0=0}var m=i1-i0,t,i;while(m){i=Math.random()*m--|0;t=array[m+i0],array[m+i0]=array[i+i0],array[i+i0]=t}return array};d3.permute=function(array,indexes){var i=indexes.length,permutes=new Array(i);while(i--)permutes[i]=array[indexes[i]];return permutes};d3.pairs=function(array){var i=0,n=array.length-1,p0,p1=array[0],pairs=new Array(n<0?0:n);while(i=0){array=arrays[n];m=array.length;while(--m>=0){merged[--j]=array[m]}}return merged};var abs=Math.abs;d3.range=function(start,stop,step){if(arguments.length<3){step=1;if(arguments.length<2){stop=start;start=0}}if((stop-start)\/step===Infinity)throw new Error("infinite range");var range=[],k=d3_range_integerScale(abs(step)),i=-1,j;start*=k,stop*=k,step*=k;if(step<0)while((j=start+step*++i)>stop)range.push(j\/k);else while((j=start+step*++i)=keys.length)return rollup?rollup.call(nest,array):sortValues?array.sort(sortValues):array;var i=-1,n=array.length,key=keys[depth++],keyValue,object,setter,valuesByKey=new d3_Map,values;while(++i=keys.length)return map;var array=[],sortKey=sortKeys[depth++];map.forEach(function(key,keyMap){array.push({key:key,values:entries(keyMap,depth)})});return sortKey?array.sort(function(a,b){return sortKey(a.key,b.key)}):array}nest.map=function(array,mapType){return map(mapType,array,0)};nest.entries=function(array){return entries(map(d3.map,array,0),0)};nest.key=function(d){keys.push(d);return nest};nest.sortKeys=function(order){sortKeys[keys.length-1]=order;return nest};nest.sortValues=function(order){sortValues=order;return nest};nest.rollup=function(f){rollup=f;return nest};return nest};d3.set=function(array){var set=new d3_Set;if(array)for(var i=0,n=array.length;i=0){name=type.slice(i+1);type=type.slice(0,i)}if(type)return arguments.length<2?this[type].on(name):this[type].on(name,listener);if(arguments.length===2){if(listener==null)for(type in this){if(this.hasOwnProperty(type))this[type].on(name,null)}return this}};function d3_dispatch_event(dispatch){var listeners=[],listenerByName=new d3_Map;function event(){var z=listeners,i=-1,n=z.length,l;while(++i=0){prefix=name.slice(0,i);name=name.slice(i+1)}return d3_nsPrefix.hasOwnProperty(prefix)?{space:d3_nsPrefix[prefix],local:name}:name}};d3_selectionPrototype.attr=function(name,value){if(arguments.length<2){if(typeof name==="string"){var node=this.node();name=d3.ns.qualify(name);return name.local?node.getAttributeNS(name.space,name.local):node.getAttribute(name)}for(value in name)this.each(d3_selection_attr(value,name[value]));return this}return this.each(d3_selection_attr(name,value))};function d3_selection_attr(name,value){name=d3.ns.qualify(name);function attrNull(){this.removeAttribute(name)}function attrNullNS(){this.removeAttributeNS(name.space,name.local)}function attrConstant(){this.setAttribute(name,value)}function attrConstantNS(){this.setAttributeNS(name.space,name.local,value)}function attrFunction(){var x=value.apply(this,arguments);if(x==null)this.removeAttribute(name);else this.setAttribute(name,x)}function attrFunctionNS(){var x=value.apply(this,arguments);if(x==null)this.removeAttributeNS(name.space,name.local);else this.setAttributeNS(name.space,name.local,x)}return value==null?name.local?attrNullNS:attrNull:typeof value==="function"?name.local?attrFunctionNS:attrFunction:name.local?attrConstantNS:attrConstant}function d3_collapse(s){return s.trim().replace(\/\\s+\/g," ")}d3_selectionPrototype.classed=function(name,value){if(arguments.length<2){if(typeof name==="string"){var node=this.node(),n=(name=d3_selection_classes(name)).length,i=-1;if(value=node.classList){while(++i=0;){if(node=group[i]){if(next&&next!==node.nextSibling)next.parentNode.insertBefore(node,next);next=node}}}return this};d3_selectionPrototype.sort=function(comparator){comparator=d3_selection_sortComparator.apply(this,arguments);for(var j=-1,m=this.length;++j=i0)i0=i+1;while(!(node=group[i0])&&++i00)type=type.slice(0,i);var filter=d3_selection_onFilters.get(type);if(filter)type=filter,wrap=d3_selection_onFilter;function onRemove(){var l=this[name];if(l){this.removeEventListener(type,l,l.$);delete this[name]}}function onAdd(){var l=wrap(listener,d3_array(arguments));onRemove.call(this);this.addEventListener(type,this[name]=l,l.$=capture);l._=listener}function removeAll(){var re=new RegExp("^__on([^.]+)"+d3.requote(type)+"$"),match;for(var name in this){if(match=name.match(re)){var l=this[name];this.removeEventListener(match[1],l,l.$);delete this[name]}}}return i?listener?onAdd:onRemove:listener?d3_noop:removeAll}var d3_selection_onFilters=d3.map({mouseenter:"mouseover",mouseleave:"mouseout"});if(d3_document){d3_selection_onFilters.forEach(function(k){if("on"+k in d3_document)d3_selection_onFilters.remove(k)})}function d3_selection_onListener(listener,argumentz){return function(e){var o=d3.event;d3.event=e;argumentz[0]=this.__data__;try{listener.apply(this,argumentz)}finally{d3.event=o}}}function d3_selection_onFilter(listener,argumentz){var l=d3_selection_onListener(listener,argumentz);return function(e){var target=this,related=e.relatedTarget;if(!related||related!==target&&!(related.compareDocumentPosition(target)&8)){l.call(target,e)}}}var d3_event_dragSelect,d3_event_dragId=0;function d3_event_dragSuppress(node){var name=".dragsuppress-"+ ++d3_event_dragId,click="click"+name,w=d3.select(d3_window(node)).on("touchmove"+name,d3_eventPreventDefault).on("dragstart"+name,d3_eventPreventDefault).on("selectstart"+name,d3_eventPreventDefault);if(d3_event_dragSelect==null){d3_event_dragSelect="onselectstart"in node?false:d3_vendorSymbol(node.style,"userSelect")}if(d3_event_dragSelect){var style=d3_documentElement(node).style,select=style[d3_event_dragSelect];style[d3_event_dragSelect]="none"}return function(suppressClick){w.on(name,null);if(d3_event_dragSelect)style[d3_event_dragSelect]=select;if(suppressClick){var off=function(){w.on(click,null)};w.on(click,function(){d3_eventPreventDefault();off()},true);setTimeout(off,0)}}}d3.mouse=function(container){return d3_mousePoint(container,d3_eventSource())};var d3_mouse_bug44083=this.navigator&&\/WebKit\/.test(this.navigator.userAgent)?-1:0;function d3_mousePoint(container,e){if(e.changedTouches)e=e.changedTouches[0];var svg=container.ownerSVGElement||container;if(svg.createSVGPoint){var point=svg.createSVGPoint();if(d3_mouse_bug44083<0){var window=d3_window(container);if(window.scrollX||window.scrollY){svg=d3.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var ctm=svg[0][0].getScreenCTM();d3_mouse_bug44083=!(ctm.f||ctm.e);svg.remove()}}if(d3_mouse_bug44083)point.x=e.pageX,point.y=e.pageY;else point.x=e.clientX,point.y=e.clientY;point=point.matrixTransform(container.getScreenCTM().inverse());return[point.x,point.y]}var rect=container.getBoundingClientRect();return[e.clientX-rect.left-container.clientLeft,e.clientY-rect.top-container.clientTop]}d3.touch=function(container,touches,identifier){if(arguments.length<3)identifier=touches,touches=d3_eventSource().changedTouches;if(touches)for(var i=0,n=touches.length,touch;i0?1:x<0?-1:0}function d3_cross2d(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])}function d3_acos(x){return x>1?0:x<-1?π:Math.acos(x)}function d3_asin(x){return x>1?halfπ:x<-1?-halfπ:Math.asin(x)}function d3_sinh(x){return((x=Math.exp(x))-1\/x)\/2}function d3_cosh(x){return((x=Math.exp(x))+1\/x)\/2}function d3_tanh(x){return((x=Math.exp(2*x))-1)\/(x+1)}function d3_haversin(x){return(x=Math.sin(x\/2))*x}var ρ=Math.SQRT2,ρ2=2,ρ4=4;d3.interpolateZoom=function(p0,p1){var ux0=p0[0],uy0=p0[1],w0=p0[2],ux1=p1[0],uy1=p1[1],w1=p1[2];var dx=ux1-ux0,dy=uy1-uy0,d2=dx*dx+dy*dy,d1=Math.sqrt(d2),b0=(w1*w1-w0*w0+ρ4*d2)\/(2*w0*ρ2*d1),b1=(w1*w1-w0*w0-ρ4*d2)\/(2*w1*ρ2*d1),r0=Math.log(Math.sqrt(b0*b0+1)-b0),r1=Math.log(Math.sqrt(b1*b1+1)-b1),dr=r1-r0,S=(dr||Math.log(w1\/w0))\/ρ;function interpolate(t){var s=t*S;if(dr){var coshr0=d3_cosh(r0),u=w0\/(ρ2*d1)*(coshr0*d3_tanh(ρ*s+r0)-d3_sinh(r0));$/;" f update.exit phpunit/coverage/js/d3.min.js /^!function(){var d3={version:"3.5.5"};var d3_arraySlice=[].slice,d3_array=function(list){return d3_arraySlice.call(list)};var d3_document=this.document;function d3_documentElement(node){return node&&(node.ownerDocument||node.document||node).documentElement}function d3_window(node){return node&&(node.ownerDocument&&node.ownerDocument.defaultView||node.document&&node||node.defaultView)}if(d3_document){try{d3_array(d3_document.documentElement.childNodes)[0].nodeType}catch(e){d3_array=function(list){var i=list.length,array=new Array(i);while(i--)array[i]=list[i];return array}}}if(!Date.now)Date.now=function(){return+new Date};if(d3_document){try{d3_document.createElement("DIV").style.setProperty("opacity",0,"")}catch(error){var d3_element_prototype=this.Element.prototype,d3_element_setAttribute=d3_element_prototype.setAttribute,d3_element_setAttributeNS=d3_element_prototype.setAttributeNS,d3_style_prototype=this.CSSStyleDeclaration.prototype,d3_style_setProperty=d3_style_prototype.setProperty;d3_element_prototype.setAttribute=function(name,value){d3_element_setAttribute.call(this,name,value+"")};d3_element_prototype.setAttributeNS=function(space,local,value){d3_element_setAttributeNS.call(this,space,local,value+"")};d3_style_prototype.setProperty=function(name,value,priority){d3_style_setProperty.call(this,name,value+"",priority)}}}d3.ascending=d3_ascending;function d3_ascending(a,b){return ab?1:a>=b?0:NaN}d3.descending=function(a,b){return ba?1:b>=a?0:NaN};d3.min=function(array,f){var i=-1,n=array.length,a,b;if(arguments.length===1){while(++i=b){a=b;break}while(++ib)a=b}else{while(++i=b){a=b;break}while(++ib)a=b}return a};d3.max=function(array,f){var i=-1,n=array.length,a,b;if(arguments.length===1){while(++i=b){a=b;break}while(++ia)a=b}else{while(++i=b){a=b;break}while(++ia)a=b}return a};d3.extent=function(array,f){var i=-1,n=array.length,a,b,c;if(arguments.length===1){while(++i=b){a=c=b;break}while(++ib)a=b;if(c=b){a=c=b;break}while(++ib)a=b;if(c1)return s\/(j-1)};d3.deviation=function(){var v=d3.variance.apply(this,arguments);return v?Math.sqrt(v):v};function d3_bisector(compare){return{left:function(a,x,lo,hi){if(arguments.length<3)lo=0;if(arguments.length<4)hi=a.length;while(lo>>1;if(compare(a[mid],x)<0)lo=mid+1;else hi=mid}return lo},right:function(a,x,lo,hi){if(arguments.length<3)lo=0;if(arguments.length<4)hi=a.length;while(lo>>1;if(compare(a[mid],x)>0)hi=mid;else lo=mid+1}return lo}}}var d3_bisect=d3_bisector(d3_ascending);d3.bisectLeft=d3_bisect.left;d3.bisect=d3.bisectRight=d3_bisect.right;d3.bisector=function(f){return d3_bisector(f.length===1?function(d,x){return d3_ascending(f(d),x)}:f)};d3.shuffle=function(array,i0,i1){if((m=arguments.length)<3){i1=array.length;if(m<2)i0=0}var m=i1-i0,t,i;while(m){i=Math.random()*m--|0;t=array[m+i0],array[m+i0]=array[i+i0],array[i+i0]=t}return array};d3.permute=function(array,indexes){var i=indexes.length,permutes=new Array(i);while(i--)permutes[i]=array[indexes[i]];return permutes};d3.pairs=function(array){var i=0,n=array.length-1,p0,p1=array[0],pairs=new Array(n<0?0:n);while(i=0){array=arrays[n];m=array.length;while(--m>=0){merged[--j]=array[m]}}return merged};var abs=Math.abs;d3.range=function(start,stop,step){if(arguments.length<3){step=1;if(arguments.length<2){stop=start;start=0}}if((stop-start)\/step===Infinity)throw new Error("infinite range");var range=[],k=d3_range_integerScale(abs(step)),i=-1,j;start*=k,stop*=k,step*=k;if(step<0)while((j=start+step*++i)>stop)range.push(j\/k);else while((j=start+step*++i)=keys.length)return rollup?rollup.call(nest,array):sortValues?array.sort(sortValues):array;var i=-1,n=array.length,key=keys[depth++],keyValue,object,setter,valuesByKey=new d3_Map,values;while(++i=keys.length)return map;var array=[],sortKey=sortKeys[depth++];map.forEach(function(key,keyMap){array.push({key:key,values:entries(keyMap,depth)})});return sortKey?array.sort(function(a,b){return sortKey(a.key,b.key)}):array}nest.map=function(array,mapType){return map(mapType,array,0)};nest.entries=function(array){return entries(map(d3.map,array,0),0)};nest.key=function(d){keys.push(d);return nest};nest.sortKeys=function(order){sortKeys[keys.length-1]=order;return nest};nest.sortValues=function(order){sortValues=order;return nest};nest.rollup=function(f){rollup=f;return nest};return nest};d3.set=function(array){var set=new d3_Set;if(array)for(var i=0,n=array.length;i=0){name=type.slice(i+1);type=type.slice(0,i)}if(type)return arguments.length<2?this[type].on(name):this[type].on(name,listener);if(arguments.length===2){if(listener==null)for(type in this){if(this.hasOwnProperty(type))this[type].on(name,null)}return this}};function d3_dispatch_event(dispatch){var listeners=[],listenerByName=new d3_Map;function event(){var z=listeners,i=-1,n=z.length,l;while(++i=0){prefix=name.slice(0,i);name=name.slice(i+1)}return d3_nsPrefix.hasOwnProperty(prefix)?{space:d3_nsPrefix[prefix],local:name}:name}};d3_selectionPrototype.attr=function(name,value){if(arguments.length<2){if(typeof name==="string"){var node=this.node();name=d3.ns.qualify(name);return name.local?node.getAttributeNS(name.space,name.local):node.getAttribute(name)}for(value in name)this.each(d3_selection_attr(value,name[value]));return this}return this.each(d3_selection_attr(name,value))};function d3_selection_attr(name,value){name=d3.ns.qualify(name);function attrNull(){this.removeAttribute(name)}function attrNullNS(){this.removeAttributeNS(name.space,name.local)}function attrConstant(){this.setAttribute(name,value)}function attrConstantNS(){this.setAttributeNS(name.space,name.local,value)}function attrFunction(){var x=value.apply(this,arguments);if(x==null)this.removeAttribute(name);else this.setAttribute(name,x)}function attrFunctionNS(){var x=value.apply(this,arguments);if(x==null)this.removeAttributeNS(name.space,name.local);else this.setAttributeNS(name.space,name.local,x)}return value==null?name.local?attrNullNS:attrNull:typeof value==="function"?name.local?attrFunctionNS:attrFunction:name.local?attrConstantNS:attrConstant}function d3_collapse(s){return s.trim().replace(\/\\s+\/g," ")}d3_selectionPrototype.classed=function(name,value){if(arguments.length<2){if(typeof name==="string"){var node=this.node(),n=(name=d3_selection_classes(name)).length,i=-1;if(value=node.classList){while(++i=0;){if(node=group[i]){if(next&&next!==node.nextSibling)next.parentNode.insertBefore(node,next);next=node}}}return this};d3_selectionPrototype.sort=function(comparator){comparator=d3_selection_sortComparator.apply(this,arguments);for(var j=-1,m=this.length;++j=i0)i0=i+1;while(!(node=group[i0])&&++i00)type=type.slice(0,i);var filter=d3_selection_onFilters.get(type);if(filter)type=filter,wrap=d3_selection_onFilter;function onRemove(){var l=this[name];if(l){this.removeEventListener(type,l,l.$);delete this[name]}}function onAdd(){var l=wrap(listener,d3_array(arguments));onRemove.call(this);this.addEventListener(type,this[name]=l,l.$=capture);l._=listener}function removeAll(){var re=new RegExp("^__on([^.]+)"+d3.requote(type)+"$"),match;for(var name in this){if(match=name.match(re)){var l=this[name];this.removeEventListener(match[1],l,l.$);delete this[name]}}}return i?listener?onAdd:onRemove:listener?d3_noop:removeAll}var d3_selection_onFilters=d3.map({mouseenter:"mouseover",mouseleave:"mouseout"});if(d3_document){d3_selection_onFilters.forEach(function(k){if("on"+k in d3_document)d3_selection_onFilters.remove(k)})}function d3_selection_onListener(listener,argumentz){return function(e){var o=d3.event;d3.event=e;argumentz[0]=this.__data__;try{listener.apply(this,argumentz)}finally{d3.event=o}}}function d3_selection_onFilter(listener,argumentz){var l=d3_selection_onListener(listener,argumentz);return function(e){var target=this,related=e.relatedTarget;if(!related||related!==target&&!(related.compareDocumentPosition(target)&8)){l.call(target,e)}}}var d3_event_dragSelect,d3_event_dragId=0;function d3_event_dragSuppress(node){var name=".dragsuppress-"+ ++d3_event_dragId,click="click"+name,w=d3.select(d3_window(node)).on("touchmove"+name,d3_eventPreventDefault).on("dragstart"+name,d3_eventPreventDefault).on("selectstart"+name,d3_eventPreventDefault);if(d3_event_dragSelect==null){d3_event_dragSelect="onselectstart"in node?false:d3_vendorSymbol(node.style,"userSelect")}if(d3_event_dragSelect){var style=d3_documentElement(node).style,select=style[d3_event_dragSelect];style[d3_event_dragSelect]="none"}return function(suppressClick){w.on(name,null);if(d3_event_dragSelect)style[d3_event_dragSelect]=select;if(suppressClick){var off=function(){w.on(click,null)};w.on(click,function(){d3_eventPreventDefault();off()},true);setTimeout(off,0)}}}d3.mouse=function(container){return d3_mousePoint(container,d3_eventSource())};var d3_mouse_bug44083=this.navigator&&\/WebKit\/.test(this.navigator.userAgent)?-1:0;function d3_mousePoint(container,e){if(e.changedTouches)e=e.changedTouches[0];var svg=container.ownerSVGElement||container;if(svg.createSVGPoint){var point=svg.createSVGPoint();if(d3_mouse_bug44083<0){var window=d3_window(container);if(window.scrollX||window.scrollY){svg=d3.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var ctm=svg[0][0].getScreenCTM();d3_mouse_bug44083=!(ctm.f||ctm.e);svg.remove()}}if(d3_mouse_bug44083)point.x=e.pageX,point.y=e.pageY;else point.x=e.clientX,point.y=e.clientY;point=point.matrixTransform(container.getScreenCTM().inverse());return[point.x,point.y]}var rect=container.getBoundingClientRect();return[e.clientX-rect.left-container.clientLeft,e.clientY-rect.top-container.clientTop]}d3.touch=function(container,touches,identifier){if(arguments.length<3)identifier=touches,touches=d3_eventSource().changedTouches;if(touches)for(var i=0,n=touches.length,touch;i0?1:x<0?-1:0}function d3_cross2d(a,b,c){return(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])}function d3_acos(x){return x>1?0:x<-1?π:Math.acos(x)}function d3_asin(x){return x>1?halfπ:x<-1?-halfπ:Math.asin(x)}function d3_sinh(x){return((x=Math.exp(x))-1\/x)\/2}function d3_cosh(x){return((x=Math.exp(x))+1\/x)\/2}function d3_tanh(x){return((x=Math.exp(2*x))-1)\/(x+1)}function d3_haversin(x){return(x=Math.sin(x\/2))*x}var ρ=Math.SQRT2,ρ2=2,ρ4=4;d3.interpolateZoom=function(p0,p1){var ux0=p0[0],uy0=p0[1],w0=p0[2],ux1=p1[0],uy1=p1[1],w1=p1[2];var dx=ux1-ux0,dy=uy1-uy0,d2=dx*dx+dy*dy,d1=Math.sqrt(d2),b0=(w1*w1-w0*w0+ρ4*d2)\/(2*w0*ρ2*d1),b1=(w1*w1-w0*w0-ρ4*d2)\/(2*w1*ρ2*d1),r0=Math.log(Math.sqrt(b0*b0+1)-b0),r1=Math.log(Math.sqrt(b1*b1+1)-b1),dr=r1-r0,S=(dr||Math.log(w1\/w0))\/ρ;function interpolate(t){var s=t*S;if(dr){var coshr0=d3_cosh(r0),u=w0\/(ρ2*d1)*(coshr0*d3_tanh(ρ*s+r0)-d3_sinh(r0));$/;" f update_token manager/sessionManager.php /^ private static function update_token(){$/;" f @@ -4352,7 +4359,8 @@ wrapper.setPaths js/lib/highcharts/js/highcharts-3d.src.js /^ };$/;" f wrapper.show js/lib/highcharts/js/highcharts-3d.src.js /^ };$/;" c xAccessor phpunit/coverage/js/nv.d3.min.js /^(function(){var nv=window.nv||{};window.nv=nv;nv.dev=false;nv.tooltip=nv.tooltip||{};nv.utils=nv.utils||{};nv.models=nv.models||{};nv.charts={};nv.graphs=[];nv.logs={};nv.dispatch=d3.dispatch("render_start","render_end");if(!Function.prototype.bind){Function.prototype.bind=function(oThis){if(typeof this!=="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=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}}if(nv.dev){nv.dispatch.on("render_start",function(e){nv.logs.startTime=+new Date});nv.dispatch.on("render_end",function(e){nv.logs.endTime=+new Date;nv.logs.totalTime=nv.logs.endTime-nv.logs.startTime;nv.log("total",nv.logs.totalTime)})}nv.log=function(){if(nv.dev&&window.console&&console.log&&console.log.apply)console.log.apply(console,arguments);else if(nv.dev&&window.console&&typeof console.log=="function"&&Function.prototype.bind){var log=Function.prototype.bind.call(console.log,console);log.apply(console,arguments)}return arguments[arguments.length-1]};nv.deprecated=function(name){if(nv.dev&&console&&console.warn){console.warn("`"+name+"` has been deprecated.")}};nv.render=function render(step){step=step||1;nv.render.active=true;nv.dispatch.render_start();setTimeout(function(){var chart,graph;for(var i=0;iavailableWidth||mouseY>availableHeight||d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined||mouseOutAnyReason){if(isMSIE){if(d3.event.relatedTarget&&d3.event.relatedTarget.ownerSVGElement===undefined&&d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass)){return}}dispatch.elementMouseout({mouseX:mouseX,mouseY:mouseY});layer.renderGuideLine(null);return}var pointXValue=xScale.invert(mouseX);dispatch.elementMousemove({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue});if(d3.event.type==="dblclick"){dispatch.elementDblclick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}if(d3.event.type==="click"){dispatch.elementClick({mouseX:mouseX,mouseY:mouseY,pointXValue:pointXValue})}}svgContainer.on("mousemove",mouseHandler,true).on("mouseout",mouseHandler,true).on("dblclick",mouseHandler).on("click",mouseHandler);layer.renderGuideLine=function(x){if(!showGuideLine)return;var line=wrap.select(".nv-interactiveGuideLine").selectAll("line").data(x!=null?[nv.utils.NaNtoZero(x)]:[],String);line.enter().append("line").attr("class","nv-guideline").attr("x1",function(d){return d}).attr("x2",function(d){return d}).attr("y1",availableHeight).attr("y2",0);line.exit().remove()}})}layer.dispatch=dispatch;layer.tooltip=tooltip;layer.margin=function(_){if(!arguments.length)return margin;margin.top=typeof _.top!="undefined"?_.top:margin.top;margin.left=typeof _.left!="undefined"?_.left:margin.left;return layer};layer.width=function(_){if(!arguments.length)return width;width=_;return layer};layer.height=function(_){if(!arguments.length)return height;height=_;return layer};layer.xScale=function(_){if(!arguments.length)return xScale;xScale=_;return layer};layer.showGuideLine=function(_){if(!arguments.length)return showGuideLine;showGuideLine=_;return layer};layer.svgContainer=function(_){if(!arguments.length)return svgContainer;svgContainer=_;return layer};return layer};nv.interactiveBisect=function(values,searchVal,xAccessor){"use strict";if(!(values instanceof Array)){return null}if(typeof xAccessor!=="function"){xAccessor=function(d,i){return d.x}}var bisect=d3.bisector(xAccessor).left;var index=d3.max([0,bisect(values,searchVal)-1]);var currentValue=xAccessor(values[index],index);if(typeof currentValue==="undefined"){currentValue=index}if(currentValue===searchVal){return index}var nextIndex=d3.min([index+1,values.length-1]);var nextValue=xAccessor(values[nextIndex],nextIndex);if(typeof nextValue==="undefined"){nextValue=nextIndex}if(Math.abs(nextValue-searchVal)>=Math.abs(currentValue-searchVal)){return index}else{return nextIndex}};nv.nearestValueIndex=function(values,searchVal,threshold){"use strict";var yDistMax=Infinity,indexToHighlight=null;values.forEach(function(d,i){var delta=Math.abs(searchVal-d);if(delta<=yDistMax&&delta"+d.footer+"<\/div>";return html};var dataSeriesExists=function(d){if(d&&d.series&&d.series.length>0){return true}return false};function convertViewBoxRatio(){if(chartContainer){var svg=d3.select(chartContainer);if(svg.node().tagName!=="svg"){svg=svg.select("svg")}var viewBox=svg.node()?svg.attr("viewBox"):null;if(viewBox){viewBox=viewBox.split(" ");var ratio=parseInt(svg.style("width"))\/viewBox[2];position.left=position.left*ratio;position.top=position.top*ratio}}}function getTooltipContainer(newContent){var body;if(chartContainer){body=d3.select(chartContainer)}else{body=d3.select("body")}var container=body.select(".nvtooltip");if(container.node()===null){container=body.append("div").attr("class","nvtooltip "+(classes?classes:"xy-tooltip")).attr("id",id)}container.node().innerHTML=newContent;container.style("top",0).style("left",0).style("opacity",0);container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true);container.classed(nvPointerEventsClass,true);return container.node()}function nvtooltip(){if(!enabled)return;if(!dataSeriesExists(data))return;convertViewBoxRatio();var left=position.left;var top=fixedTop!=null?fixedTop:position.top;var container=getTooltipContainer(contentGenerator(data));tooltipElem=container;if(chartContainer){var svgComp=chartContainer.getElementsByTagName("svg")[0];var boundRect=svgComp?svgComp.getBoundingClientRect():chartContainer.getBoundingClientRect();var svgOffset={left:0,top:0};if(svgComp){var svgBound=svgComp.getBoundingClientRect();var chartBound=chartContainer.getBoundingClientRect();var svgBoundTop=svgBound.top;if(svgBoundTop<0){var containerBound=chartContainer.getBoundingClientRect();svgBoundTop=Math.abs(svgBoundTop)>containerBound.height?0:svgBoundTop}svgOffset.top=Math.abs(svgBoundTop-chartBound.top);svgOffset.left=Math.abs(svgBound.left-chartBound.left)}left+=chartContainer.offsetLeft+svgOffset.left-2*chartContainer.scrollLeft;top+=chartContainer.offsetTop+svgOffset.top-2*chartContainer.scrollTop}if(snapDistance&&snapDistance>0){top=Math.floor(top\/snapDistance)*snapDistance}nv.tooltip.calcTooltipPosition([left,top],gravity,distance,container);return nvtooltip}nvtooltip.nvPointerEventsClass=nvPointerEventsClass;nvtooltip.content=function(_){if(!arguments.length)return content;content=_;return nvtooltip};nvtooltip.tooltipElem=function(){return tooltipElem};nvtooltip.contentGenerator=function(_){if(!arguments.length)return contentGenerator;if(typeof _==="function"){contentGenerator=_}return nvtooltip};nvtooltip.data=function(_){if(!arguments.length)return data;data=_;return nvtooltip};nvtooltip.gravity=function(_){if(!arguments.length)return gravity;gravity=_;return nvtooltip};nvtooltip.distance=function(_){if(!arguments.length)return distance;distance=_;return nvtooltip};nvtooltip.snapDistance=function(_){if(!arguments.length)return snapDistance;snapDistance=_;return nvtooltip};nvtooltip.classes=function(_){if(!arguments.length)return classes;classes=_;return nvtooltip};nvtooltip.chartContainer=function(_){if(!arguments.length)return chartContainer;chartContainer=_;return nvtooltip};nvtooltip.position=function(_){if(!arguments.length)return position;position.left=typeof _.left!=="undefined"?_.left:position.left;position.top=typeof _.top!=="undefined"?_.top:position.top;return nvtooltip};nvtooltip.fixedTop=function(_){if(!arguments.length)return fixedTop;fixedTop=_;return nvtooltip};nvtooltip.enabled=function(_){if(!arguments.length)return enabled;enabled=_;return nvtooltip};nvtooltip.valueFormatter=function(_){if(!arguments.length)return valueFormatter;if(typeof _==="function"){valueFormatter=_}return nvtooltip};nvtooltip.headerFormatter=function(_){if(!arguments.length)return headerFormatter;if(typeof _==="function"){headerFormatter=_}return nvtooltip};nvtooltip.id=function(){return id};return nvtooltip};nv.tooltip.show=function(pos,content,gravity,dist,parentContainer,classes){var container=document.createElement("div");container.className="nvtooltip "+(classes?classes:"xy-tooltip");var body=parentContainer;if(!parentContainer||parentContainer.tagName.match(\/g|svg\/i)){body=document.getElementsByTagName("body")[0]}container.style.left=0;container.style.top=0;container.style.opacity=0;if(typeof content!=="string")container.appendChild(content);else container.innerHTML=content;body.appendChild(container);if(parentContainer){pos[0]=pos[0]-parentContainer.scrollLeft;pos[1]=pos[1]-parentContainer.scrollTop}nv.tooltip.calcTooltipPosition(pos,gravity,dist,container)};nv.tooltip.findFirstNonSVGParent=function(Elem){while(Elem.tagName.match(\/^g|svg$\/i)!==null){Elem=Elem.parentNode}return Elem};nv.tooltip.findTotalOffsetTop=function(Elem,initialTop){var offsetTop=initialTop;do{if(!isNaN(Elem.offsetTop)){offsetTop+=Elem.offsetTop}}while(Elem=Elem.offsetParent);return offsetTop};nv.tooltip.findTotalOffsetLeft=function(Elem,initialLeft){var offsetLeft=initialLeft;do{if(!isNaN(Elem.offsetLeft)){offsetLeft+=Elem.offsetLeft}}while(Elem=Elem.offsetParent);return offsetLeft};nv.tooltip.calcTooltipPosition=function(pos,gravity,dist,container){var height=parseInt(container.offsetHeight),width=parseInt(container.offsetWidth),windowWidth=nv.utils.windowSize().width,windowHeight=nv.utils.windowSize().height,scrollTop=window.pageYOffset,scrollLeft=window.pageXOffset,left,top;windowHeight=window.innerWidth>=document.body.scrollWidth?windowHeight:windowHeight-16;windowWidth=window.innerHeight>=document.body.scrollHeight?windowWidth:windowWidth-16;gravity=gravity||"s";dist=dist||20;var tooltipTop=function(Elem){return nv.tooltip.findTotalOffsetTop(Elem,top)};var tooltipLeft=function(Elem){return nv.tooltip.findTotalOffsetLeft(Elem,left)};switch(gravity){case"e":left=pos[0]-width-dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftscrollLeft?pos[0]+dist:scrollLeft-tLeft+left;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"w":left=pos[0]+dist;top=pos[1]-height\/2;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeft+width>windowWidth)left=pos[0]-width-dist;if(tTopscrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"n":left=pos[0]-width\/2-5;top=pos[1]+dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(tTop+height>scrollTop+windowHeight)top=scrollTop+windowHeight-tTop+top-height;break;case"s":left=pos[0]-width\/2;top=pos[1]-height-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);if(tLeftwindowWidth)left=left-width\/2+5;if(scrollTop>tTop)top=scrollTop;break;case"none":left=pos[0];top=pos[1]-dist;var tLeft=tooltipLeft(container);var tTop=tooltipTop(container);break}container.style.left=left+"px";container.style.top=top+"px";container.style.opacity=1;container.style.position="absolute";return container};nv.tooltip.cleanup=function(){var tooltips=document.getElementsByClassName("nvtooltip");var purging=[];while(tooltips.length){purging.push(tooltips[0]);tooltips[0].style.transitionDelay="0 !important";tooltips[0].style.opacity=0;tooltips[0].className="nvtooltip-pending-removal"}setTimeout(function(){while(purging.length){var removeMe=purging.pop();removeMe.parentNode.removeChild(removeMe)}},500)}})();nv.utils.windowSize=function(){var size={width:640,height:480};if(document.body&&document.body.offsetWidth){size.width=document.body.offsetWidth;size.height=document.body.offsetHeight}if(document.compatMode=="CSS1Compat"&&document.documentElement&&document.documentElement.offsetWidth){size.width=document.documentElement.offsetWidth;size.height=document.documentElement.offsetHeight}if(window.innerWidth&&window.innerHeight){size.width=window.innerWidth;size.height=window.innerHeight}return size};nv.utils.windowResize=function(handler){if(window.addEventListener){window.addEventListener("resize",handler)}else{nv.log("ERROR: Failed to bind to window.resize with: ",handler)}return{callback:handler,clear:function(){window.removeEventListener("resize",handler)}}};nv.utils.getColor=function(color){if(!arguments.length){return nv.utils.defaultColor()}else if(color instanceof Array){return function(d,i){return d.color||color[i%color.length]}}else{return color}};nv.utils.defaultColor=function(){var colors=d3.scale.category20().range();return function(d,i){return d.color||colors[i%colors.length]}};nv.utils.customTheme=function(dictionary,getKey,defaultColors){getKey=getKey||function(series){return series.key};defaultColors=defaultColors||d3.scale.category20().range();var defIndex=defaultColors.length;return function(series,index){var key=getKey(series);if(typeof dictionary[key]==="function"){return dictionary[key]()}else if(dictionary[key]!==undefined){return dictionary[key]}else{if(!defIndex){defIndex=defaultColors.length}defIndex=defIndex-1;return defaultColors[defIndex]}}};nv.utils.pjax=function(links,content){var load=function(href){d3.html(href,function(fragment){var target=d3.select(content).node();target.parentNode.replaceChild(d3.select(fragment).select(content).node(),target);nv.utils.pjax(links,content)})};d3.selectAll(links).on("click",function(){history.pushState(this.href,this.textContent,this.href);load(this.href);d3.event.preventDefault()});d3.select(window).on("popstate",function(){if(d3.event.state){load(d3.event.state)}})};nv.utils.calcApproxTextWidth=function(svgTextElem){if(typeof svgTextElem.style==="function"&&typeof svgTextElem.text==="function"){var fontSize=parseInt(svgTextElem.style("font-size").replace("px",""));var textLength=svgTextElem.text().length;return textLength*fontSize*.5}return 0};nv.utils.NaNtoZero=function(n){if(typeof n!=="number"||isNaN(n)||n===null||n===Infinity||n===-Infinity){return 0}return n};d3.selection.prototype.watchTransition=function(renderWatch){var args=[this].concat([].slice.call(arguments,1));return renderWatch.transition.apply(renderWatch,args)};nv.utils.renderWatch=function(dispatch,duration){if(!(this instanceof nv.utils.renderWatch)){return new nv.utils.renderWatch(dispatch,duration)}var _duration=duration!==undefined?duration:250;var renderStack=[];var self=this;this.models=function(models){models=[].slice.call(arguments,0);models.forEach(function(model){model.__rendered=false;(function(m){m.dispatch.on("renderEnd",function(arg){m.__rendered=true;self.renderEnd("model")})})(model);if(renderStack.indexOf(model)<0){renderStack.push(model)}});return this};this.reset=function(duration){if(duration!==undefined){_duration=duration}renderStack=[]};this.transition=function(selection,args,duration){args=arguments.length>1?[].slice.call(arguments,1):[];if(args.length>1){duration=args.pop()}else{duration=_duration!==undefined?_duration:250}selection.__rendered=false;if(renderStack.indexOf(selection)<0){renderStack.push(selection)}if(duration===0){selection.__rendered=true;selection.delay=function(){return this};selection.duration=function(){return this};return selection}else{if(selection.length===0){selection.__rendered=true}else if(selection.every(function(d){return!d.length})){selection.__rendered=true}else{selection.__rendered=false}var n=0;return selection.transition().duration(duration).each(function(){++n}).each("end",function(d,i){if(--n===0){selection.__rendered=true;self.renderEnd.apply(this,args)}})}};this.renderEnd=function(){if(renderStack.every(function(d){return d.__rendered})){renderStack.forEach(function(d){d.__rendered=false});dispatch.renderEnd.apply(this,arguments)}}};nv.utils.deepExtend=function(dst){var sources=arguments.length>1?[].slice.call(arguments,1):[];sources.forEach(function(source){for(key in source){var isArray=dst[key]instanceof Array;var isObject=typeof dst[key]==="object";var srcObj=typeof source[key]==="object";if(isObject&&!isArray&&srcObj){nv.utils.deepExtend(dst[key],source[key])}else{dst[key]=source[key]}}})};nv.utils.state=function(){if(!(this instanceof nv.utils.state)){return new nv.utils.state}var state={};var _self=this;var _setState=function(){};var _getState=function(){return{}};var init=null;var changed=null;this.dispatch=d3.dispatch("change","set");this.dispatch.on("set",function(state){_setState(state,true)});this.getter=function(fn){_getState=fn;return this};this.setter=function(fn,callback){if(!callback){callback=function(){}}_setState=function(state,update){fn(state);if(update){callback()}};return this};this.init=function(state){init=init||{};nv.utils.deepExtend(init,state)};var _set=function(){var settings=_getState();if(JSON.stringify(settings)===JSON.stringify(state)){return false}for(var key in settings){if(state[key]===undefined){state[key]={}}state[key]=settings[key];changed=true}return true};this.update=function(){if(init){_setState(init,false);init=null}if(_set.call(this)){this.dispatch.change(state)}}};nv.utils.optionsFunc=function(args){nv.deprecated("nv.utils.optionsFunc");if(args){d3.map(args).forEach(function(key,value){if(typeof this[key]==="function"){this[key](value)}}.bind(this))}return this};nv.utils.calcTicksX=function(numTicks,data){var numValues=1;var i=0;for(i;inumValues?stream_len:numValues}nv.log("Requested number of ticks: ",numTicks);nv.log("Calculated max values to be: ",numValues);numTicks=numTicks>numValues?numTicks=numValues-1:numTicks;numTicks=numTicks<1?1:numTicks;numTicks=Math.floor(numTicks);nv.log("Calculating tick count as: ",numTicks);return numTicks};nv.utils.calcTicksY=function(numTicks,data){return nv.utils.calcTicksX(numTicks,data)};nv.utils.initOption=function(chart,name){if(chart._calls&&chart._calls[name]){chart[name]=chart._calls[name]}else{chart[name]=function(_){if(!arguments.length)return chart._options[name];chart._options[name]=_;return chart}}};nv.utils.initOptions=function(chart){var ops=Object.getOwnPropertyNames(chart._options||{});var calls=Object.getOwnPropertyNames(chart._calls||{});ops=ops.concat(calls);for(var i in ops){nv.utils.initOption(chart,ops[i])}};nv.utils.inheritOptionsD3=function(target,d3_source,oplist){target._d3options=oplist.concat(target._d3options||[]);oplist.unshift(d3_source);oplist.unshift(target);d3.rebind.apply(this,oplist)};nv.utils.arrayUnique=function(a){return a.sort().filter(function(item,pos){return!pos||item!=a[pos-1]})};nv.utils.symbolMap=d3.map();nv.utils.symbol=function(){var type,size=64;function symbol(d,i){var t=type.call(this,d,i);var s=size.call(this,d,i);if(d3.svg.symbolTypes.indexOf(t)!==-1){return d3.svg.symbol().type(t).size(s)()}else{return nv.utils.symbolMap.get(t)(s)}}symbol.type=function(_){if(!arguments.length)return type;type=d3.functor(_);return symbol};symbol.size=function(_){if(!arguments.length)return size;size=d3.functor(_);return symbol};return symbol};nv.utils.inheritOptions=function(target,source){var ops=Object.getOwnPropertyNames(source._options||{});var calls=Object.getOwnPropertyNames(source._calls||{});var inherited=source._inherited||[];var d3ops=source._d3options||[];var args=ops.concat(calls).concat(inherited).concat(d3ops);args.unshift(source);args.unshift(target);d3.rebind.apply(this,args);target._inherited=nv.utils.arrayUnique(ops.concat(calls).concat(inherited).concat(ops).concat(target._inherited||[]));target._d3options=nv.utils.arrayUnique(d3ops.concat(target._d3options||[]))};nv.utils.initSVG=function(svg){svg.classed({"nvd3-svg":true})};nv.models.axis=function(){"use strict";var axis=d3.svg.axis();var scale=d3.scale.linear();var margin={top:0,right:0,bottom:0,left:0},width=75,height=60,axisLabelText=null,showMaxMin=true,highlightZero=true,rotateLabels=0,rotateYLabel=true,staggerLabels=false,isOrdinal=false,ticks=null,axisLabelDistance=0,duration=250,dispatch=d3.dispatch("renderEnd"),axisRendered=false,maxMinRendered=false;axis.scale(scale).orient("bottom").tickFormat(function(d){return d});var scale0;var renderWatch=nv.utils.renderWatch(dispatch,duration);function chart(selection){renderWatch.reset();selection.each(function(data){var container=d3.select(this);nv.utils.initSVG(container);var wrap=container.selectAll("g.nv-wrap.nv-axis").data([data]);var wrapEnter=wrap.enter().append("g").attr("class","nvd3 nv-wrap nv-axis");var gEnter=wrapEnter.append("g");var g=wrap.select("g");if(ticks!==null)axis.ticks(ticks);else if(axis.orient()=="top"||axis.orient()=="bottom")axis.ticks(Math.abs(scale.range()[1]-scale.range()[0])\/100);g.watchTransition(renderWatch,"axis").call(axis);scale0=scale0||axis.scale();var fmt=axis.tickFormat();if(fmt==null){fmt=scale0.tickFormat()}var axisLabel=g.selectAll("text.nv-axislabel").data([axisLabelText||null]);axisLabel.exit().remove();switch(axis.orient()){case"top":axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",0).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-axis.tickPadding()).attr("text-anchor","middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max top").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale.range()[i])+",0)"})}break;case"bottom":var xLabelMargin=axisLabelDistance+36;var maxTextWidth=30;var xTicks=g.selectAll("g").select("text");if(rotateLabels%360){xTicks.each(function(d,i){var width=this.getBoundingClientRect().width;if(width>maxTextWidth)maxTextWidth=width});var sin=Math.abs(Math.sin(rotateLabels*Math.PI\/180));var xLabelMargin=(sin?sin*maxTextWidth:maxTextWidth)+30;xTicks.attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels%360>0?"start":"end")}axisLabel.enter().append("text").attr("class","nv-axislabel");var w;if(scale.range().length<2){w=0}else if(scale.range().length===2){w=scale.range()[1]}else{w=scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0])}axisLabel.attr("text-anchor","middle").attr("y",xLabelMargin).attr("x",w\/2);if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data([scale.domain()[0],scale.domain()[scale.domain().length-1]]);axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text");axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",axis.tickPadding()).attr("transform",function(d,i,j){return"rotate("+rotateLabels+" 0,0)"}).style("text-anchor",rotateLabels?rotateLabels%360>0?"start":"end":"middle").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max bottom").attr("transform",function(d,i){return"translate("+nv.utils.NaNtoZero(scale(d)+(isOrdinal?scale.rangeBand()\/2:0))+",0)"})}if(staggerLabels)xTicks.attr("transform",function(d,i){return"translate(0,"+(i%2==0?"0":"12")+")"});break;case"right":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"begin").attr("transform",rotateYLabel?"rotate(90)":"").attr("y",rotateYLabel?-Math.max(margin.right,width)+12:-10).attr("x",rotateYLabel?scale.range()[0]\/2:axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",axis.tickPadding()).style("text-anchor","start").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break;case"left":axisLabel.enter().append("text").attr("class","nv-axislabel");axisLabel.style("text-anchor",rotateYLabel?"middle":"end").attr("transform",rotateYLabel?"rotate(-90)":"").attr("y",rotateYLabel?-Math.max(margin.left,width)+25-(axisLabelDistance||0):-10).attr("x",rotateYLabel?-scale.range()[0]\/2:-axis.tickPadding());if(showMaxMin){var axisMaxMin=wrap.selectAll("g.nv-axisMaxMin").data(scale.domain());axisMaxMin.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0);axisMaxMin.exit().remove();axisMaxMin.attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale0(d))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-axis.tickPadding()).attr("text-anchor","end").text(function(d,i){var v=fmt(d);return(""+v).match("NaN")?"":v});axisMaxMin.watchTransition(renderWatch,"min-max right").attr("transform",function(d,i){return"translate(0,"+nv.utils.NaNtoZero(scale.range()[i])+")"}).select("text").style("opacity",1)}break}axisLabel.text(function(d){return d});if(showMaxMin&&(axis.orient()==="left"||axis.orient()==="right")){g.selectAll("g").each(function(d,i){d3.select(this).select("text").attr("opacity",1);if(scale(d)scale.range()[0]-10){if(d>1e-10||d<-1e-10)d3.select(this).attr("opacity",0);d3.select(this).select("text").attr("opacity",0)}});if(scale.domain()[0]==scale.domain()[1]&&scale.domain()[0]==0){wrap.selectAll("g.nv-axisMaxMin").style("opacity",function(d,i){return!i?1:0})}}if(showMaxMin&&(axis.orient()==="top"||axis.orient()==="bottom")){var maxMinRange=[];wrap.selectAll("g.nv-axisMaxMin").each(function(d,i){try{if(i)maxMinRange.push(scale(d)-this.getBoundingClientRect().width-4);else maxMinRange.push(scale(d)+this.getBoundingClientRect().width+4)}catch(err){if(i)maxMinRange.push(scale(d)-4);else maxMinRange.push(scale(d)+4)}});g.selectAll("g").each(function(d,i){if(scale(d)maxMinRange[1]){if(d>1e-10||d<-1e-10)d3.select(this).remove();else d3.select(this).select("text").remove()}})}if(highlightZero){g.selectAll(".tick").filter(function(d){return!parseFloat(Math.round(this.__data__*1e5)\/1e6)&&this.__data__!==undefined}).classed("zero",true)}scale0=scale.copy()});renderWatch.renderEnd("axis immediate");return chart}chart.axis=axis;chart.dispatch=dispatch;chart.options=nv.utils.optionsFunc.bind(chart);chart._options=Object.create({},{axisLabelDistance:{get:function(){return axisLabelDistance},set:function(_){axisLabelDistance=_}},staggerLabels:{get:function(){return staggerLabels},set:function(_){staggerLabels=_}},rotateLabels:{get:function(){return rotateLabels},set:function(_){rotateLabels=_}},rotateYLabel:{get:function(){return rotateYLabel},set:function(_){rotateYLabel=_}},highlightZero:{get:function(){return highlightZero},set:function(_){highlightZero=_}},showMaxMin:{get:function(){return showMaxMin},set:function(_){showMaxMin=_}},axisLabel:{get:function(){return axisLabelText},set:function(_){axisLabelText=_}},height:{get:function(){return height},set:function(_){height=_}},ticks:{get:function(){return ticks},set:function(_){ticks=_}},width:{get:function(){return width},set:function(_){width=_}},margin:{get:function(){return margin},set:function(_){margin.top=_.top!==undefined?_.top:margin.top;margin.right=_.right!==undefined?_.right:margin.right;margin.bottom=_.bottom!==undefined?_.bottom:margin.bottom;margin.left=_.left!==undefined?_.left:margin.left}},duration:{get:function(){return duration},set:function(_){duration=_;renderWatch.reset(duration)}},scale:{get:function(){return scale},set:function(_){scale=_;axis.scale(scale);isOrdinal=typeof scale.rangeBands==="function";nv.utils.inheritOptionsD3(chart,scale,["domain","range","rangeBand","rangeBands"])}}});nv.utils.initOptions(chart);nv.utils.inheritOptionsD3(chart,axis,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]);$/;" f xhr js/lib/api.js /^ this.xhr[i].onreadystatechange = function(){$/;" f -xml manager/module/call_log.php /^ $xml = simplexml_load_string($content);$/;" v +xml manager/module/call_log.php /^ $xml = simplexml_load_string($filecontent);$/;" v +xml manager/module/call_log.php /^ $xml = simplexml_load_string($filecontent);$/;" v zoom.center phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f zoom.duration phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f zoom.event phpunit/coverage/js/d3.min.js /^return[ux0+u*dx,uy0+u*dy,w0*coshr0\/d3_cosh(ρ*s+r0)]}return[ux0+t*dx,uy0+t*dy,w0*Math.exp(ρ*s)]}interpolate.duration=S*1e3;return interpolate};d3.behavior.zoom=function(){var view={x:0,y:0,k:1},translate0,center0,center,size=[960,500],scaleExtent=d3_behavior_zoomInfinity,duration=250,zooming=0,mousedown="mousedown.zoom",mousemove="mousemove.zoom",mouseup="mouseup.zoom",mousewheelTimer,touchstart="touchstart.zoom",touchtime,event=d3_eventDispatch(zoom,"zoomstart","zoom","zoomend"),x0,x1,y0,y1;if(!d3_behavior_zoomWheel){d3_behavior_zoomWheel="onwheel"in d3_document?(d3_behavior_zoomDelta=function(){return-d3.event.deltaY*(d3.event.deltaMode?120:1)},"wheel"):"onmousewheel"in d3_document?(d3_behavior_zoomDelta=function(){return d3.event.wheelDelta},"mousewheel"):(d3_behavior_zoomDelta=function(){return-d3.event.detail},"MozMousePixelScroll")}function zoom(g){g.on(mousedown,mousedowned).on(d3_behavior_zoomWheel+".zoom",mousewheeled).on("dblclick.zoom",dblclicked).on(touchstart,touchstarted)}zoom.event=function(g){g.each(function(){var dispatch=event.of(this,arguments),view1=view;if(d3_transitionInheritId){d3.select(this).transition().each("start.zoom",function(){view=this.__chart__||{x:0,y:0,k:1};zoomstarted(dispatch)}).tween("zoom:zoom",function(){var dx=size[0],dy=size[1],cx=center0?center0[0]:dx\/2,cy=center0?center0[1]:dy\/2,i=d3.interpolateZoom([(cx-view.x)\/view.k,(cy-view.y)\/view.k,dx\/view.k],[(cx-view1.x)\/view1.k,(cy-view1.y)\/view1.k,dx\/view1.k]);return function(t){var l=i(t),k=dx\/l[2];this.__chart__=view={x:cx-l[0]*k,y:cy-l[1]*k,k:k};zoomed(dispatch)}}).each("interrupt.zoom",function(){zoomended(dispatch)}).each("end.zoom",function(){zoomended(dispatch)})}else{this.__chart__=view;zoomstarted(dispatch);zoomed(dispatch);zoomended(dispatch)}})};zoom.translate=function(_){if(!arguments.length)return[view.x,view.y];view={x:+_[0],y:+_[1],k:view.k};rescale();return zoom};zoom.scale=function(_){if(!arguments.length)return view.k;view={x:view.x,y:view.y,k:+_};rescale();return zoom};zoom.scaleExtent=function(_){if(!arguments.length)return scaleExtent;scaleExtent=_==null?d3_behavior_zoomInfinity:[+_[0],+_[1]];return zoom};zoom.center=function(_){if(!arguments.length)return center;center=_&&[+_[0],+_[1]];return zoom};zoom.size=function(_){if(!arguments.length)return size;size=_&&[+_[0],+_[1]];return zoom};zoom.duration=function(_){if(!arguments.length)return duration;duration=+_;return zoom};zoom.x=function(z){if(!arguments.length)return x1;x1=z;x0=z.copy();view={x:0,y:0,k:1};return zoom};zoom.y=function(z){if(!arguments.length)return y1;y1=z;y0=z.copy();view={x:0,y:0,k:1};return zoom};function location(p){return[(p[0]-view.x)\/view.k,(p[1]-view.y)\/view.k]}function point(l){return[l[0]*view.k+view.x,l[1]*view.k+view.y]}function scaleTo(s){view.k=Math.max(scaleExtent[0],Math.min(scaleExtent[1],s))}function translateTo(p,l){l=point(l);view.x+=p[0]-l[0];view.y+=p[1]-l[1]}function zoomTo(that,p,l,k){that.__chart__={x:view.x,y:view.y,k:view.k};scaleTo(Math.pow(2,k));translateTo(center0=p,l);that=d3.select(that);if(duration>0)that=that.transition().duration(duration);that.call(zoom.event)}function rescale(){if(x1)x1.domain(x0.range().map(function(x){return(x-view.x)\/view.k}).map(x0.invert));if(y1)y1.domain(y0.range().map(function(y){return(y-view.y)\/view.k}).map(y0.invert))}function zoomstarted(dispatch){if(!zooming++)dispatch({type:"zoomstart"})}function zoomed(dispatch){rescale();dispatch({type:"zoom",scale:view.k,translate:[view.x,view.y]})}function zoomended(dispatch){if(!--zooming)dispatch({type:"zoomend"});center0=null}function mousedowned(){var that=this,target=d3.event.target,dispatch=event.of(that,arguments),dragged=0,subject=d3.select(d3_window(that)).on(mousemove,moved).on(mouseup,ended),location0=location(d3.mouse(that)),dragRestore=d3_event_dragSuppress(that);d3_selection_interrupt.call(that);zoomstarted(dispatch);function moved(){dragged=1;translateTo(d3.mouse(that),location0);zoomed(dispatch)}function ended(){subject.on(mousemove,null).on(mouseup,null);dragRestore(dragged&&d3.event.target===target);zoomended(dispatch)}}function touchstarted(){var that=this,dispatch=event.of(that,arguments),locations0={},distance0=0,scale0,zoomName=".zoom-"+d3.event.changedTouches[0].identifier,touchmove="touchmove"+zoomName,touchend="touchend"+zoomName,targets=[],subject=d3.select(that),dragRestore=d3_event_dragSuppress(that);started();zoomstarted(dispatch);subject.on(mousedown,null).on(touchstart,started);function relocate(){var touches=d3.touches(that);scale0=view.k;touches.forEach(function(t){if(t.identifier in locations0)locations0[t.identifier]=location(t)});return touches}function started(){var target=d3.event.target;d3.select(target).on(touchmove,moved).on(touchend,ended);targets.push(target);var changed=d3.event.changedTouches;for(var i=0,n=changed.length;i1){var p=touches[0],q=touches[1],dx=p[0]-q[0],dy=p[1]-q[1];distance0=dx*dx+dy*dy}}function moved(){var touches=d3.touches(that),p0,l0,p1,l1;d3_selection_interrupt.call(that);for(var i=0,n=touches.length;i1?1:s;l=l<0?0:l>1?1:l;m2=l<=.5?l*(1+s):l+s-l*s;m1=2*l-m2;function v(h){if(h>360)h-=360;else if(h<0)h+=360;if(h<60)return m1+(m2-m1)*h\/60;if(h<180)return m2;if(h<240)return m1+(m2-m1)*(240-h)\/60;return m1}function vv(h){return Math.round(v(h)*255)}return new d3_rgb(vv(h+120),vv(h),vv(h-120))}d3.hcl=d3_hcl;function d3_hcl(h,c,l){return this instanceof d3_hcl?void(this.h=+h,this.c=+c,this.l=+l):arguments.length<2?h instanceof d3_hcl?new d3_hcl(h.h,h.c,h.l):h instanceof d3_lab?d3_lab_hcl(h.l,h.a,h.b):d3_lab_hcl((h=d3_rgb_lab((h=d3.rgb(h)).r,h.g,h.b)).l,h.a,h.b):new d3_hcl(h,c,l)}var d3_hclPrototype=d3_hcl.prototype=new d3_color;d3_hclPrototype.brighter=function(k){return new d3_hcl(this.h,this.c,Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.darker=function(k){return new d3_hcl(this.h,this.c,Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)))};d3_hclPrototype.rgb=function(){return d3_hcl_lab(this.h,this.c,this.l).rgb()};function d3_hcl_lab(h,c,l){if(isNaN(h))h=0;if(isNaN(c))c=0;return new d3_lab(l,Math.cos(h*=d3_radians)*c,Math.sin(h)*c)}d3.lab=d3_lab;function d3_lab(l,a,b){return this instanceof d3_lab?void(this.l=+l,this.a=+a,this.b=+b):arguments.length<2?l instanceof d3_lab?new d3_lab(l.l,l.a,l.b):l instanceof d3_hcl?d3_hcl_lab(l.h,l.c,l.l):d3_rgb_lab((l=d3_rgb(l)).r,l.g,l.b):new d3_lab(l,a,b)}var d3_lab_K=18;var d3_lab_X=.95047,d3_lab_Y=1,d3_lab_Z=1.08883;var d3_labPrototype=d3_lab.prototype=new d3_color;d3_labPrototype.brighter=function(k){return new d3_lab(Math.min(100,this.l+d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.darker=function(k){return new d3_lab(Math.max(0,this.l-d3_lab_K*(arguments.length?k:1)),this.a,this.b)};d3_labPrototype.rgb=function(){return d3_lab_rgb(this.l,this.a,this.b)};function d3_lab_rgb(l,a,b){var y=(l+16)\/116,x=y+a\/500,z=y-b\/200;x=d3_lab_xyz(x)*d3_lab_X;y=d3_lab_xyz(y)*d3_lab_Y;z=d3_lab_xyz(z)*d3_lab_Z;return new d3_rgb(d3_xyz_rgb(3.2404542*x-1.5371385*y-.4985314*z),d3_xyz_rgb(-.969266*x+1.8760108*y+.041556*z),d3_xyz_rgb(.0556434*x-.2040259*y+1.0572252*z))}function d3_lab_hcl(l,a,b){return l>0?new d3_hcl(Math.atan2(b,a)*d3_degrees,Math.sqrt(a*a+b*b),l):new d3_hcl(NaN,NaN,l)}function d3_lab_xyz(x){return x>.206893034?x*x*x:(x-4\/29)\/7.787037}function d3_xyz_lab(x){return x>.008856?Math.pow(x,1\/3):7.787037*x+4\/29}function d3_xyz_rgb(r){return Math.round(255*(r<=.00304?12.92*r:1.055*Math.pow(r,1\/2.4)-.055))}d3.rgb=d3_rgb;function d3_rgb(r,g,b){return this instanceof d3_rgb?void(this.r=~~r,this.g=~~g,this.b=~~b):arguments.length<2?r instanceof d3_rgb?new d3_rgb(r.r,r.g,r.b):d3_rgb_parse(""+r,d3_rgb,d3_hsl_rgb):new d3_rgb(r,g,b)}function d3_rgbNumber(value){return new d3_rgb(value>>16,value>>8&255,value&255)}function d3_rgbString(value){return d3_rgbNumber(value)+""}var d3_rgbPrototype=d3_rgb.prototype=new d3_color;d3_rgbPrototype.brighter=function(k){k=Math.pow(.7,arguments.length?k:1);var r=this.r,g=this.g,b=this.b,i=30;if(!r&&!g&&!b)return new d3_rgb(i,i,i);if(r&&r>4;r=r>>4|r;g=color&240;g=g>>4|g;b=color&15;b=b<<4|b}else if(format.length===7){r=(color&16711680)>>16;g=(color&65280)>>8;b=color&255}}return rgb(r,g,b)}function d3_rgb_hsl(r,g,b){var min=Math.min(r\/=255,g\/=255,b\/=255),max=Math.max(r,g,b),d=max-min,h,s,l=(max+min)\/2;if(d){s=l<.5?d\/(max+min):d\/(2-max-min);if(r==max)h=(g-b)\/d+(g0&&l<1?0:h}return new d3_hsl(h,s,l)}function d3_rgb_lab(r,g,b){r=d3_rgb_xyz(r);g=d3_rgb_xyz(g);b=d3_rgb_xyz(b);var x=d3_xyz_lab((.4124564*r+.3575761*g+.1804375*b)\/d3_lab_X),y=d3_xyz_lab((.2126729*r+.7151522*g+.072175*b)\/d3_lab_Y),z=d3_xyz_lab((.0193339*r+.119192*g+.9503041*b)\/d3_lab_Z);return d3_lab(116*y-16,500*(x-y),200*(y-z))}function d3_rgb_xyz(r){return(r\/=255)<=.04045?r\/12.92:Math.pow((r+.055)\/1.055,2.4)}function d3_rgb_parseNumber(c){var f=parseFloat(c);return c.charAt(c.length-1)==="%"?Math.round(f*2.55):f}var d3_rgb_names=d3.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});d3_rgb_names.forEach(function(key,value){d3_rgb_names.set(key,d3_rgbNumber(value))});function d3_functor(v){return typeof v==="function"?v:function(){return v}}d3.functor=d3_functor;d3.xhr=d3_xhrType(d3_identity);function d3_xhrType(response){return function(url,mimeType,callback){if(arguments.length===2&&typeof mimeType==="function")callback=mimeType,mimeType=null;return d3_xhr(url,mimeType,response,callback)}}function d3_xhr(url,mimeType,response,callback){var xhr={},dispatch=d3.dispatch("beforesend","progress","load","error"),headers={},request=new XMLHttpRequest,responseType=null;if(this.XDomainRequest&&!("withCredentials"in request)&&\/^(http(s)?:)?\\\/\\\/\/.test(url))request=new XDomainRequest;"onload"in request?request.onload=request.onerror=respond:request.onreadystatechange=function(){request.readyState>3&&respond()};function respond(){var status=request.status,result;if(!status&&d3_xhrHasResponse(request)||status>=200&&status<300||status===304){try{result=response.call(xhr,request)}catch(e){dispatch.error.call(xhr,e);return}dispatch.load.call(xhr,result)}else{dispatch.error.call(xhr,request)}}request.onprogress=function(event){var o=d3.event;d3.event=event;try{dispatch.progress.call(xhr,request)}finally{d3.event=o}};xhr.header=function(name,value){name=(name+"").toLowerCase();if(arguments.length<2)return headers[name];if(value==null)delete headers[name];else headers[name]=value+"";return xhr};xhr.mimeType=function(value){if(!arguments.length)return mimeType;mimeType=value==null?null:value+"";return xhr};xhr.responseType=function(value){if(!arguments.length)return responseType;responseType=value;return xhr};xhr.response=function(value){response=value;return xhr};["get","post"].forEach(function(method){xhr[method]=function(){return xhr.send.apply(xhr,[method].concat(d3_array(arguments)))}});xhr.send=function(method,data,callback){if(arguments.length===2&&typeof data==="function")callback=data,data=null;request.open(method,url,true);if(mimeType!=null&&!("accept"in headers))headers["accept"]=mimeType+",*\/*";if(request.setRequestHeader)for(var name in headers)request.setRequestHeader(name,headers[name]);if(mimeType!=null&&request.overrideMimeType)request.overrideMimeType(mimeType);if(responseType!=null)request.responseType=responseType;if(callback!=null)xhr.on("error",callback).on("load",function(request){callback(null,request)});dispatch.beforesend.call(xhr,request);request.send(data==null?null:data);return xhr};xhr.abort=function(){request.abort();return xhr};d3.rebind(xhr,dispatch,"on");return callback==null?xhr:xhr.get(d3_xhr_fixCallback(callback))}function d3_xhr_fixCallback(callback){return callback.length===1?function(error,request){callback(error==null?request:null)}:callback}function d3_xhrHasResponse(request){var type=request.responseType;return type&&type!=="text"?request.response:request.responseText}d3.dsv=function(delimiter,mimeType){var reFormat=new RegExp('["'+delimiter+"\\n]"),delimiterCode=delimiter.charCodeAt(0);function dsv(url,row,callback){if(arguments.length<3)callback=row,row=null;var xhr=d3_xhr(url,mimeType,row==null?response:typedResponse(row),callback);xhr.row=function(_){return arguments.length?xhr.response((row=_)==null?response:typedResponse(_)):row};return xhr}function response(request){return dsv.parse(request.responseText)}function typedResponse(f){return function(request){return dsv.parse(request.responseText,f)}}dsv.parse=function(text,f){var o;return dsv.parseRows(text,function(row,i){if(o)return o(row,i-1);var a=new Function("d","return {"+row.map(function(name,i){return JSON.stringify(name)+": d["+i+"]"}).join(",")+"}");o=f?function(row,i){return f(a(row),i)}:a})};dsv.parseRows=function(text,f){var EOL={},EOF={},rows=[],N=text.length,I=0,n=0,t,eol;function token(){if(I>=N)return EOF;if(eol)return eol=false,EOL;var j=I;if(text.charCodeAt(j)===34){var i=j;while(i++24){if(isFinite(delay)){clearTimeout(d3_timer_timeout);d3_timer_timeout=setTimeout(d3_timer_step,delay)}d3_timer_interval=0}else{d3_timer_interval=1;d3_timer_frame(d3_timer_step)}}d3.timer.flush=function(){d3_timer_mark();d3_timer_sweep()};function d3_timer_mark(){var now=Date.now();d3_timer_active=d3_timer_queueHead;while(d3_timer_active){if(now>=d3_timer_active.t)d3_timer_active.f=d3_timer_active.c(now-d3_timer_active.t);d3_timer_active=d3_timer_active.n}return now}function d3_timer_sweep(){var t0,t1=d3_timer_queueHead,time=Infinity;while(t1){if(t1.f){t1=t0?t0.n=t1.n:d3_timer_queueHead=t1.n}else{if(t1.t8?function(d){return d\/k}:function(d){return d*k},symbol:d}}function d3_locale_numberFormat(locale){var locale_decimal=locale.decimal,locale_thousands=locale.thousands,locale_grouping=locale.grouping,locale_currency=locale.currency,formatGroup=locale_grouping&&locale_thousands?function(value,width){var i=value.length,t=[],j=0,g=locale_grouping[0],length=0;while(i>0&&g>0){if(length+g+1>width)g=Math.max(1,width-length);t.push(value.substring(i-=g,i+g));if((length+=g+1)>width)break;g=locale_grouping[j=(j+1)%locale_grouping.length]}return t.reverse().join(locale_thousands)}:d3_identity;return function(specifier){var match=d3_format_re.exec(specifier),fill=match[1]||" ",align=match[2]||">",sign=match[3]||"-",symbol=match[4]||"",zfill=match[5],width=+match[6],comma=match[7],precision=match[8],type=match[9],scale=1,prefix="",suffix="",integer=false,exponent=true;if(precision)precision=+precision.substring(1);if(zfill||fill==="0"&&align==="="){zfill=fill="0";align="="}switch(type){case"n":comma=true;type="g";break;case"%":scale=100;suffix="%";type="f";break;case"p":scale=100;suffix="%";type="r";break;case"b":case"o":case"x":case"X":if(symbol==="#")prefix="0"+type.toLowerCase();case"c":exponent=false;case"d":integer=true;precision=0;break;case"s":scale=-1;type="r";break}if(symbol==="$")prefix=locale_currency[0],suffix=locale_currency[1];if(type=="r"&&!precision)type="g";if(precision!=null){if(type=="g")precision=Math.max(1,Math.min(21,precision));else if(type=="e"||type=="f")precision=Math.max(0,Math.min(20,precision))}type=d3_format_types.get(type)||d3_format_typeDefault;var zcomma=zfill&,return function(value){var fullSuffix=suffix;if(integer&&value%1)return"";var negative=value<0||value===0&&1\/value<0?(value=-value,"-"):sign==="-"?"":sign;if(scale<0){var unit=d3.formatPrefix(value,precision);value=unit.scale(value);fullSuffix=unit.symbol+suffix}else{value*=scale}value=type(value,precision);var i=value.lastIndexOf("."),before,after;if(i<0){var j=exponent?value.lastIndexOf("e"):-1;if(j<0)before=value,after="";else before=value.substring(0,j),after=value.substring(j)}else{before=value.substring(0,i);after=locale_decimal+value.substring(i+1)}if(!zfill&&comma)before=formatGroup(before,Infinity);var length=prefix.length+before.length+after.length+(zcomma?0:negative.length),padding=length"?padding+negative+value:align==="^"?padding.substring(0,length>>=1)+negative+value+padding.substring(length):negative+(zcomma?value:padding+value))+fullSuffix}}}var d3_format_re=\/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?\/i;var d3_format_types=d3.map({b:function(x){return x.toString(2)},c:function(x){return String.fromCharCode(x)},o:function(x){return x.toString(8)},x:function(x){return x.toString(16)},X:function(x){return x.toString(16).toUpperCase()},g:function(x,p){return x.toPrecision(p)},e:function(x,p){return x.toExponential(p)},f:function(x,p){return x.toFixed(p)},r:function(x,p){return(x=d3.round(x,d3_format_precision(x,p))).toFixed(Math.max(0,Math.min(20,d3_format_precision(x*(1+1e-15),p))))}});function d3_format_typeDefault(x){return x+""}var d3_time=d3.time={},d3_date=Date;function d3_date_utc(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}d3_date_utc.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){d3_time_prototype.setUTCDate.apply(this._,arguments)},setDay:function(){d3_time_prototype.setUTCDay.apply(this._,arguments)},setFullYear:function(){d3_time_prototype.setUTCFullYear.apply(this._,arguments)},setHours:function(){d3_time_prototype.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){d3_time_prototype.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){d3_time_prototype.setUTCMinutes.apply(this._,arguments)},setMonth:function(){d3_time_prototype.setUTCMonth.apply(this._,arguments)},setSeconds:function(){d3_time_prototype.setUTCSeconds.apply(this._,arguments)},setTime:function(){d3_time_prototype.setTime.apply(this._,arguments)}};var d3_time_prototype=Date.prototype;function d3_time_interval(local,step,number){function round(date){var d0=local(date),d1=offset(d0,1);return date-d01){while(time=m)return-1;c=template.charCodeAt(i++);if(c===37){t=template.charAt(i++);p=d3_time_parsers[t in d3_time_formatPads?template.charAt(i++):t];if(!p||(j=p(date,string,j))<0)return-1}else if(c!=string.charCodeAt(j++)){return-1}}return j}d3_time_format.utc=function(template){var local=d3_time_format(template);function format(date){try{d3_date=d3_date_utc;var utc=new d3_date;utc._=date;return local(utc)}finally{d3_date=Date}}format.parse=function(string){try{d3_date=d3_date_utc;var date=local.parse(string);return date&&date._}finally{d3_date=Date}};format.toString=local.toString;return format};d3_time_format.multi=d3_time_format.utc.multi=d3_time_formatMulti;var d3_time_periodLookup=d3.map(),d3_time_dayRe=d3_time_formatRe(locale_days),d3_time_dayLookup=d3_time_formatLookup(locale_days),d3_time_dayAbbrevRe=d3_time_formatRe(locale_shortDays),d3_time_dayAbbrevLookup=d3_time_formatLookup(locale_shortDays),d3_time_monthRe=d3_time_formatRe(locale_months),d3_time_monthLookup=d3_time_formatLookup(locale_months),d3_time_monthAbbrevRe=d3_time_formatRe(locale_shortMonths),d3_time_monthAbbrevLookup=d3_time_formatLookup(locale_shortMonths);$/;" f From d4295d08c2f0edf08f2cef0813e6999b8c771008 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 17:01:11 +0200 Subject: [PATCH 04/21] minmod --- config/database.json | 2 +- css/header.scss | 20 ++++++++++---------- js/includes/sociogram.js | 25 ++++++++++++------------- js/lib/page-manager.js | 4 ++-- manager/module/call_log.php | 2 +- view.php | 10 +++++----- 6 files changed, 31 insertions(+), 32 deletions(-) diff --git a/config/database.json b/config/database.json index 8859117..e18d45e 100755 --- a/config/database.json +++ b/config/database.json @@ -3,4 +3,4 @@ "dbname" : "socioview", "user" : "php", "password" : "QbzjZACndQM6NmuD" -} \ No newline at end of file +} diff --git a/css/header.scss b/css/header.scss index 318749d..5562efc 100755 --- a/css/header.scss +++ b/css/header.scss @@ -2,7 +2,7 @@ #WRAPPER > #HEADER{ - + /* [1] Barre de recherche =========================================================*/ & > #searchbar{ @@ -12,14 +12,14 @@ left: 1em; width: 20em; height: 2em; - + padding: .2em 1em; border: 0; border-radius: 3px; background-color: $theme-bg; - + } /* [2] Informations utilisateur @@ -51,7 +51,7 @@ cursor: pointer; } - + /* (2) Image du profil */ & > #user-picture{ @@ -62,7 +62,7 @@ width: calc( #{$header-height} - 2*1em ); height: calc( #{$header-height} - 2*1em ); - + border-radius: 50% / 50%; background: $theme-bg url('/f/svg/nopic/st/header') center center no-repeat; @@ -98,7 +98,7 @@ } - + /* [3] Menu deroulant pour l'administration du profil =========================================================*/ @@ -109,7 +109,7 @@ right: 0; margin: .5em; - + border-radius: 5px; border: 1px solid darken($theme-bg, 10); @@ -122,7 +122,7 @@ & > span{ display: block; position: relative; - + // On ajoute une ligne en dessous sauf pour le dernier &:not(:last-child){ border-bottom: 1px solid #ddd; @@ -140,8 +140,8 @@ } } - - + + } diff --git a/js/includes/sociogram.js b/js/includes/sociogram.js index 9739c08..2a44e92 100644 --- a/js/includes/sociogram.js +++ b/js/includes/sociogram.js @@ -18,7 +18,7 @@ function sociogramClass(container){ this.container = container; this.log('sociogram created'); -}; +} @@ -122,7 +122,7 @@ sociogramClass.prototype.load = function(){ thisPtr.log(response); // Si erreur, on quitte - if( response.ModuleError != 0 ) return; + if( response.ModuleError !== 0 ) return; // On enregistre la réponse thisPtr.response = response; @@ -204,10 +204,9 @@ sociogramClass.prototype.load = function(){ sociogramClass.prototype.nodeAt = function(x, y){ var nodes = this.sigma.graph.nodes(); var minDistance = null; - - for( nodeId in nodes ){ + for( var nodeId in nodes ){ var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); - if( minDistance == null || distance < minDistance ) + if( minDistance === null || distance < minDistance ) minDistance = distance; } @@ -232,9 +231,9 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ var node = this.sigma.graph.nodes(nodeId); // Si le noeud est deja place, on ne fais rien - if( node.x != 0 || node.y != 0 ) return; + if( node.x !== 0 || node.y !== 0 ) return; - var pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position + pos = (pos===null) ? {x: node.x, y: node.y} : pos; // On recupere la position // Tant que le noeud est trop proche d'un autre, on l'eloigne // UNIQUEMENT si alone n'est pas NULL @@ -263,7 +262,7 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ var neighborsCount = 0; - for( neighborId in neighborsId ){ + for( var neighborId in neighborsId ){ neighbors[neighborId] = this.sigma.graph.nodes(neighborId); neighborsCount++; } @@ -279,7 +278,7 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ for( neighborId in neighbors ){ var current = this.sigma.graph.nodes(neighborId); // Si n'est pas deja positionne - if( current.x == 0 && current.y == 0 ){ + if( current.x === 0 && current.y === 0 ){ // On cherche un angle tant qu'il est pas trop pres d'un deja pris var angle, alreadyUsed = false; do{ @@ -322,14 +321,14 @@ sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){ // Pile des voisins pour lesquels il faut chercher leurs voisins var stack = []; - for( neighborId in neighbors ) stack.push(neighborId); + for( var neighborId in neighbors ) stack.push(neighborId); // Tant qu'il reste des voisins a trouver while( stack.length > 0 ){ var subneighbors = this.allNeighborsIndex[stack[0]]; - for( subId in subneighbors ) + for( var subId in subneighbors ) // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins - if( neighbors[subId] == null ){ + if( neighbors[subId] === null ){ stack.push(subId); // On ajoute a la pile neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete } @@ -456,7 +455,7 @@ sociogramClass.prototype.bindings.clickNode = function(thisPtr, e){ neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique thisPtr.sigma.graph.nodes().forEach(function(n) { - if( neighborNodes[n.id] != null ) n.color = n.originalColor; + if( neighborNodes[n.id] !== null ) n.color = n.originalColor; else n.color = '#eee'; }); diff --git a/js/lib/page-manager.js b/js/lib/page-manager.js index 914e2b4..d5d2c5b 100755 --- a/js/lib/page-manager.js +++ b/js/lib/page-manager.js @@ -10,7 +10,7 @@ /* */ /***************************************/ -function pageManagerClass(){}; +function pageManagerClass(){} var ptrPageManagerClass; // pointeur global pour l'utilisation de fonctions de fonctions @@ -276,4 +276,4 @@ pageManagerClass.prototype = { return this; } -} +}; diff --git a/manager/module/call_log.php b/manager/module/call_log.php index 2f84b0b..71bd603 100644 --- a/manager/module/call_log.php +++ b/manager/module/call_log.php @@ -72,7 +72,7 @@ /* (2) On enregistre le contact dans l'annuaire s'il y est pas déjà */ if( !isset($phone_directory[$number]) ) - $phone_directory[$number] = strlen($log['Name']) ? $log['Name'] : null; + $phone_directory[$number] = strlen($log['Name']) ? (string) $log['Name'] : null; /* (3) On complète le log */ $phone_log = array( diff --git a/view.php b/view.php index e1bf85e..d9546b3 100755 --- a/view.php +++ b/view.php @@ -25,13 +25,13 @@ - - - - + + + + - + From 0192b7b0b90a1420fd34507f737ddeb476b9beb0 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 18:56:31 +0200 Subject: [PATCH 05/21] =?UTF-8?q?Modification=20de=20ModuleManager()=20pou?= =?UTF-8?q?r=20accepter=20les=20param=C3=A8tres=20optionnels=20dans=20conf?= =?UTF-8?q?ig/modules.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/modules.json | 51 +++++ manager/ModuleRequest.php | 24 +- phpunit/coverage/Database.php.html | 220 ++++++++++--------- phpunit/coverage/ManagerError.php.html | 2 +- phpunit/coverage/ResourceDispatcher.php.html | 94 ++++---- phpunit/coverage/autoloader.php.html | 2 +- phpunit/coverage/index.html | 44 ++-- phpunit/coverage/sessionManager.php.html | 2 +- phpunit/tests/ModuleRequest.php | 35 +++ 9 files changed, 289 insertions(+), 185 deletions(-) diff --git a/config/modules.json b/config/modules.json index ec462e9..6128323 100755 --- a/config/modules.json +++ b/config/modules.json @@ -15,6 +15,16 @@ } }, + "phpunitOptionalParams": { + "description": "Méthode utile à phpunit pour le test des paramètres optionnels.", + "permissions": [], + "parameters": { + "p1": { "description": "Texte", "type": "text" }, + "p2": { "description": "Texte", "type": "text", "optional": false }, + "p3": { "description": "Entier positif (optionnel)", "type": "id", "optional": true } + } + }, + "phpunitPermissions": { "description": "Méthode utile à phpunit pour le test des permissions.", "permissions": ["a", "b"], @@ -126,6 +136,47 @@ "duration": { "description": "Duree du token en nombre de jours", "type": "numeric" } } } + }, + + "subject": { + + "getById": { + "description": "Retourne les informations d'un sujet.", + "permissions": ["admin"], + "parameters": { + "id_user": { "description": "UID du sujet recherche.", "type": "id" } + } + }, + + + "getAll": { + "description": "Retourne les informations de tous les sujets.", + "permissions": ["admin"], + "parameters": {} + }, + + + "create": { + "description": "Creation d'un nouveau sujet.", + "permissions": ["admin"], + "parameters": { + "username" : { "description": "Pseudo du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "firstname" : { "description": "Prénom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "lastname" : { "description": "Nom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "id_facebook": { "description": "Id facebook du sujet (optionnel).", "type": "id", "optional": true }, + "number" : { "description": "Numéro de téléphone du sujet (optionnel).", "type": "text" } + } + }, + + + "remove": { + "description": "Suppression d'un utilisateur.", + "permissions": ["admin"], + "parameters": { + "id_user": { "description": "UID de l'utilisateur", "type": "id" } + } + } + } } diff --git a/manager/ModuleRequest.php b/manager/ModuleRequest.php index 26b8f25..bd8d15d 100755 --- a/manager/ModuleRequest.php +++ b/manager/ModuleRequest.php @@ -337,21 +337,33 @@ $method = $this->modules[$this->path['module']][$this->path['method']]; // Si le nombre de parametre en entree est insuffisant - if( count($method['parameters']) > count($params) ) return false; + // if( count($method['parameters']) > count($params) ) return false; /* [2] Si le type est defini, pour chaque param, on teste =========================================================*/ foreach($method['parameters'] as $name=>$paramsdata){ - // Si le parametre n'existe pas dans le tableau recu - if( !isset($params[$name]) ) return false; + /* (1) On récupère si le paramètre est optionnel ou pas */ + $optional = isset($paramsdata['optional']) && $paramsdata['optional'] === true; - // Si le type n'est pas defini, on reboucle + /* (2) Si le paramètre est obligatoire et qu'il n'est pas donné -> erreur */ + if( !isset($params[$name]) && !$optional ) return false; + + /* (3) Si le type n'est pas defini, on a pas besoin de le vérifier */ if( !isset($paramsdata['type']) ) continue; - // Si la verification est fausse, on retourne faux - if( !Database::check($paramsdata['type'], $params[$name]) ) return false; + /* (4) Si le paramètre est optionnel et n'est pas donné */ + if( $optional && !isset($params[$name]) ){ + // On le crée avec la valeur NULL + $params[$name] = null; + // On passe au paramètre suivant + continue; + + /* (5) Si le paramètre est renseigné */ + }else + // Si la verification est fausse, on retourne faux + if( !Database::check($paramsdata['type'], $params[$name]) ) return false; } /* [3] Gestion du retour, si tout s'est bien passe diff --git a/phpunit/coverage/Database.php.html b/phpunit/coverage/Database.php.html index e50b2c3..0211b51 100755 --- a/phpunit/coverage/Database.php.html +++ b/phpunit/coverage/Database.php.html @@ -50,23 +50,23 @@

0.00%
0 / 1
-
-
- 57.14% covered (warning) +
+
+ 42.86% covered (danger)
-
57.14%
-
4 / 7
- CRAP +
42.86%
+
3 / 7
+ CRAP
-
- 84.15% covered (warning) +
+ 83.33% covered (warning)
-
84.15%
-
69 / 82
+
83.33%
+
70 / 84
@@ -79,23 +79,23 @@
0.00%
0 / 1
-
-
- 57.14% covered (warning) +
+
+ 42.86% covered (danger)
-
57.14%
-
4 / 7
- 57.18 +
42.86%
+
3 / 7
+ 63.04
-
- 84.15% covered (warning) +
+ 83.33% covered (warning)
-
84.15%
-
69 / 82
+
83.33%
+
70 / 84
@@ -204,28 +204,28 @@ -  check -
-
- 100.00% covered (success) +  check +
+
+ 0.00% covered (danger)
-
100.00%
-
1 / 1
- 23 +
0.00%
+
0 / 1
+ 26
-
- 100.00% covered (success) +
+ 96.30% covered (success)
-
100.00%
-
25 / 25
+
96.30%
+
26 / 27
-  frDate +  frDate
0.00% covered (danger) @@ -251,12 +251,12 @@ - + - + @@ -281,8 +281,8 @@ - - + + @@ -309,7 +309,7 @@ - + @@ -356,7 +356,7 @@ - + @@ -373,19 +373,19 @@ - + - + - + - + @@ -394,14 +394,14 @@ - + - + @@ -417,8 +417,8 @@ - - + + @@ -435,17 +435,17 @@ - + - + - + @@ -458,7 +458,7 @@ - + @@ -475,78 +475,84 @@ - + - + - - + + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + +
<?php
    
    namespace manager;
    class DataBase{
        
        /* ATTRIBUTS STATIQUES */
        public static $config_path = array(
            'local'   => 'f/json/database-local/conf',
            $this->dbname   = $dbname;
            $this->username = $username;
            $this->password = $password;
            
            try{            
            try{
                self::$pdo = new \PDO('mysql:host='.$this->host.';dbname='.$this->dbname, $this->username, $this->password);
                // On signale que tout s'est bien passe
                self::$instance = new DataBase($conf['host'], $conf['dbname'], $conf['user'], $conf['password']);
            }
            
            return self::$instance;
        }
        * @fetchData<Array>                    le résultat d'une $requeteSQL->fetchAll()
        * @oneDimension<Boolean>            FAUX <=> fetchAll ; VRAI <=> fetch
        *
        * @return newFetchData<Array>        retourne le tableau donné en paramètre mais sans les valeurs à clés numériques    
        * @return newFetchData<Array>        retourne le tableau donné en paramètre mais sans les valeurs à clés numériques
        *
        */
        public static function delNumeric($fetchData, $oneDimension=false){
                // on supprime les doublons des entrées (indice numérique)
                for( $i = 0 ; $i < count($fetchData) ; $i++ ) // pour tout les utilisateurs
                    foreach($fetchData[$i] as $col => $val){  // pour toutes les entrées
                        
                        if( !mb_detect_encoding($val, 'UTF-8') )
                            $fetchData[$i][$col] = utf8_encode($val);
                        
                        if( is_int($col) ){ // Si indice numerique
                            if( $nextEquivalent ) // Si suit un indice textuel
                                unset( $fetchData[$i][$col] ); // on supprime l'indice
                            
                            $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique
                        }else // Si l'indice n'est pas un entier
                            $nextEquivalent = true; // On signale qu'il y aura peut etre un indice numerique suivant
                            
                        }
            /* [2] 1 dimensions
                // on supprime les doublons des entrées (indice numérique)
                foreach($fetchData as $i=>$val){  // pour toutes les entrées
                    
                    if( !mb_detect_encoding($val, 'UTF-8') )
                        $fetchData[$i] = utf8_encode($val);
                    if( is_int($i) ){ // Si indice numerique
                        if( $nextEquivalent ) // Si suit un indice textuel
                            unset( $fetchData[$i] ); // on supprime l'indice
                        
                        $nextEquivalent = false; // Dans tous les cas, on dit que le prochain ne pourra pas etre supprime si numerique
                    }else // Si l'indice n'est pas un entier
        ////////////////////////////////////////////////////////////////
        //                 _  __ _           _   _                 
        // __   _____ _ __(_)/ _(_) ___ __ _| |_(_) ___  _ __  ___ 
        //                 _  __ _           _   _
        // __   _____ _ __(_)/ _(_) ___ __ _| |_(_) ___  _ __  ___
        // \ \ / / _ \ '__| | |_| |/ __/ _` | __| |/ _ \| '_ \/ __|
        //  \ V /  __/ |  | |  _| | (_| (_| | |_| | (_) | | | \__ \
        //   \_/ \___|_|  |_|_| |_|\___\__,_|\__|_|\___/|_| |_|___/
        *
        */
        public static function check($type, $value){
            $checker = true;
            $checker = true;
            /* [0] On verifie que $value n'est pas nul
            =========================================================*/
            if( is_null($value) ) return false;
            if( is_null($value) ) return false;
            /* [1] Si de type VARCHAR(min, max)
            =========================================================*/
            if( preg_match('/^varchar\((\d+), ?(\d+)\)$/', $type, $match) ){
            if( preg_match('/^varchar\((\d+), ?(\d+)\)$/', $type, $match) ){
                // On recupere la taille min
                $min = (int) $match[1];
                // On recupere la taille max
            /* [2] Si de type ARRAY(type_elements)
            =========================================================*/
            if( preg_match('/^array<(.+)>$/', $type, $match) ){
            if( preg_match('/^array<(.+)>$/', $type, $match) ){
                // Si c'est pas un tableau on retourne une erreur
                if( !is_array($value) )
                    return false;
                return true;
            }
            
            /* [n] Sinon, tous les autres types definis
            =========================================================*/            
            =========================================================*/
            switch($type){
                // Entier positif (id dans BDD)
                case 'id':
                    return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0;
                case 'id':
                    return $checker && is_numeric($value) && $value <= 2147483647 && $value >= 0;
                    break;
                // String quelconque (peut etre vide)
                case 'text':
                    return $checker && is_string($value);
                case 'text':
                    return $checker && is_string($value);
                // Adresse mail (255 caracteres max)
                case 'mail':
                    return $checker && is_string($value) && strlen($value) <= 50 && preg_match('/^[\w\.-]+@[\w\.-]+\.[a-z]{2,4}$/i', $value);
                    break;
                
                // Hash sha1
                case 'sha1':
                    return $checker && is_string($value) && preg_match('/^[\da-f]{40}$/i', $value);
                    break;
                
                default:
                    return false;
                    break;
            }
            return $checker;
        }
        ////////////////////////////////////
        //      _       _            
        //   __| | __ _| |_ ___  ___ 
        //  / _` |/ _` | __/ _ \/ __|
        // | (_| | (_| | ||  __/\__ \
        //  \__,_|\__,_|\__\___||___/
        //
        ////////////////////////////////////
        // 1) Convertis une date en en francais explicite
        public static function frDate($date){
            /* [1] On definit les traductions
            =========================================================*/
            // Jours de la semaine
            $days   = array("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche");
            // Mois de l'annee
            $months = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
            /* [2] On recupere le timestamp et les indices
            =========================================================*/
            $time = strtotime($date); // timestamp
            $daynum = intval( date('N', $time)-1 ); // jour dans la semaine
            $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee
                    break;
                // Numéro de téléphone
                case 'phone_number':
                    return $checker && is_string($value) && preg_match('/^(?:0|\+33 ?|0?0?33 ?|)([1-9] ?(?:[0-9] ?){8})$/i', $value);
                    break;
                default:
                    return false;
                    break;
            }
            return $checker;
        }
        ////////////////////////////////////
        //      _       _
        //   __| | __ _| |_ ___  ___
        //  / _` |/ _` | __/ _ \/ __|
        // | (_| | (_| | ||  __/\__ \
        //  \__,_|\__,_|\__\___||___/
        //
        ////////////////////////////////////
        // 1) Convertis une date en en francais explicite
        public static function frDate($date){
            /* [1] On definit les traductions
            =========================================================*/
            // Jours de la semaine
            $days   = array("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche");
            // Mois de l'annee
            $months = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
            /* [3] On recupere les infos independemment
            =========================================================*/
            $result = array(
                $days[$daynum],     // nom de jour
                date('j', $time),   // jour du mois
                $months[$monthnum], // nom du mois
                date('Y', $time),   // annee
            );
            return implode(" ", $result);
        }
    }
?>
            /* [2] On recupere le timestamp et les indices
            =========================================================*/
            $time = strtotime($date); // timestamp
            $daynum = intval( date('N', $time)-1 ); // jour dans la semaine
            $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee
            /* [3] On recupere les infos independemment
            =========================================================*/
            $result = array(
                $days[$daynum],     // nom de jour
                date('j', $time),   // jour du mois
                $months[$monthnum], // nom du mois
                date('Y', $time),   // annee
            );
            return implode(" ", $result);
        }
    }
?>
@@ -559,7 +565,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/coverage/ManagerError.php.html b/phpunit/coverage/ManagerError.php.html index 7e86598..2f5ad2c 100755 --- a/phpunit/coverage/ManagerError.php.html +++ b/phpunit/coverage/ManagerError.php.html @@ -247,7 +247,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/coverage/ResourceDispatcher.php.html b/phpunit/coverage/ResourceDispatcher.php.html index 328077e..96b3795 100755 --- a/phpunit/coverage/ResourceDispatcher.php.html +++ b/phpunit/coverage/ResourceDispatcher.php.html @@ -262,49 +262,49 @@         *         */         public function __construct($url, $view=false){ -             $this->error = ManagerError::Success; +             $this->error = ManagerError::Success;             /* [0] On met a jour la configuration             =====================================================*/             // Extensions supportees -             $extensions_conf = json_decode( file_get_contents(__ROOT__.self::$extension_config_path), true ); +             $extensions_conf = json_decode( file_get_contents(__ROOT__.self::$extension_config_path), true );             // Gestion de l'erreur de parsage -             if( $extensions_conf == null ){ +             if( $extensions_conf == null ){                 $this->error = ManagerError::ParsingFailed;                 return false;             } -             self::$supported_extensions = $extensions_conf; +             self::$supported_extensions = $extensions_conf;             // Dossiers supportes -             $parents_conf = json_decode( file_get_contents(__ROOT__.self::$parents_config_path), true ); +             $parents_conf = json_decode( file_get_contents(__ROOT__.self::$parents_config_path), true );                          // Gestion de l'erreur de parsage -             if( $parents_conf == null ){ +             if( $parents_conf == null ){                 $this->error = ManagerError::ParsingFailed;                 return false;             } -             self::$supported_parents = $parents_conf; +             self::$supported_parents = $parents_conf;             /* [1] On recupere les donnees de l'URL             ==================================================*/ -             $serialFlags = array_slice( explode('/',$url), 1 ); +             $serialFlags = array_slice( explode('/',$url), 1 );             /* [2] On check/cree les drapeaux avec ces donnees             ==================================================*/ -             if( !$this->createFlags($serialFlags) ){ // Creation des drapeaux +             if( !$this->createFlags($serialFlags) ){ // Creation des drapeaux                 $this->error = ManagerError::InvalidFlags;                 return false;             }             /* [3] On construit le chemin a partir des tags             ==================================================*/ -             if( !$this->buildPath() ){ // Construction du chemin +             if( !$this->buildPath() ){ // Construction du chemin                 $this->error = ManagerError::UnreachableResource;                 return false;             } @@ -312,10 +312,10 @@             /* [4] On gere l'affichage pour l'appel externe/interne             ==================================================*/             if( $view ) // Appel externe -                 $this->view(); +                 $this->view();              -             return true; +             return true;         } @@ -328,8 +328,8 @@         *         */         public static function getResource($route){ -             $instance = new ResourceDispatcher($route); -             return $instance->getContent(); +             $instance = new ResourceDispatcher($route); +             return $instance->getContent();         } @@ -345,51 +345,51 @@             /* [1] Verification des flags (version serialisee)             ======================================================*/ -             $correct = true; +             $correct = true;             // Verification du nombre de drapeaux () au moins 3 -             $correct = $correct && count($serialFlags) >= 3; +             $correct = $correct && count($serialFlags) >= 3;             // Verification que l'extension est correcte -             $correct = $correct && array_key_exists($serialFlags[0], self::$supported_extensions); +             $correct = $correct && array_key_exists($serialFlags[0], self::$supported_extensions);             // Verification du filename -             $correct = $correct && preg_match('/^[\w_\.-]+$/i', $serialFlags[1]); +             $correct = $correct && preg_match('/^[\w_\.-]+$/i', $serialFlags[1]);             // Verification du parent -             $correct = $correct && array_key_exists($serialFlags[2], self::$supported_parents); +             $correct = $correct && array_key_exists($serialFlags[2], self::$supported_parents);             // Verification du sous-parent (optionnel) -             $opt_subParent = count($serialFlags) >= 4; +             $opt_subParent = count($serialFlags) >= 4;             if( $opt_subParent ) -                 $correct = $correct && preg_match('/^[\w_-]+$/i', $serialFlags[3]); +                 $correct = $correct && preg_match('/^[\w_-]+$/i', $serialFlags[3]);             // Verification de la couleur (optionnel) -             $opt_color = count($serialFlags) >= 5 && preg_match('/^[\da-f]{6,8}+$/i', $serialFlags[4]); +             $opt_color = count($serialFlags) >= 5 && preg_match('/^[\da-f]{6,8}+$/i', $serialFlags[4]); -             if( !$correct ) -                 return false; +             if( !$correct ) +                 return false;                              /* [2] Creation (non serialisee) des flags             ======================================================*/             // Si tout se deroule bien, on cree les flags -             $this->flags = array( -                 'extension' => $serialFlags[0], -                 'filename'  => $serialFlags[1], -                 'parent'    => $serialFlags[2] -             ); +             $this->flags = array( +                 'extension' => $serialFlags[0], +                 'filename'  => $serialFlags[1], +                 'parent'    => $serialFlags[2] +             );             // Ajout du sous-parent optionnel             if( $opt_subParent ) -                 $this->flags['subparent'] = $serialFlags[3]; +                 $this->flags['subparent'] = $serialFlags[3];             // Ajout du color optionnel             if( $opt_color ) -                 $this->flags['color'] = '#'.$serialFlags[4]; +                 $this->flags['color'] = '#'.$serialFlags[4]; -             return true; +             return true;         } @@ -408,10 +408,10 @@             /* [1] On recupere le HEADER associe a l'extension             ==========================================================*/             // Si aucun header pour cet cle, on retourne une erreur -             if( !isset(self::$supported_extensions[$this->flags['extension']]) ) return false; +             if( !isset(self::$supported_extensions[$this->flags['extension']]) ) return false;             // On recupere le header associe -             $header = self::$supported_extensions[$this->flags['extension']]; +             $header = self::$supported_extensions[$this->flags['extension']]; @@ -420,23 +420,23 @@             /* [2] On recupere le chemin associe au parent             ==========================================================*/             // Si aucun dossier pour cet indice, on retourne une erreur -             if( !isset(self::$supported_parents[$this->flags['parent']]) ) return false; +             if( !isset(self::$supported_parents[$this->flags['parent']]) ) return false;             // On recupere le dossier associe -             $parent = self::$supported_parents[$this->flags['parent']]; +             $parent = self::$supported_parents[$this->flags['parent']];             /* [3] Gestion du sous-parent optionnel             ==========================================================*/ -             $opt_subParent = (isset($this->flags['subparent'])) ? $this->flags['subparent'].'/' : ''; +             $opt_subParent = (isset($this->flags['subparent'])) ? $this->flags['subparent'].'/' : '';             /* [4] Gestion du color optionnel             =========================================================*/ -             $this->stylesheet = ""; +             $this->stylesheet = "";             // si le color est defini -             if( isset($this->flags['color']) ){ +             if( isset($this->flags['color']) ){                 $this->stylesheet = "\n<style type='text/css'>\n";                     $this->stylesheet .= "\t#stylisable{\n";                         $this->stylesheet .= "\t\tfill: ".$this->flags['color']." !important;\n"; @@ -449,15 +449,15 @@             /* [5] On definit le header             ==========================================================*/ -             $this->header = $header; +             $this->header = $header;             /* [6] On construit le chemin              ==========================================================*/ -             $this->path = __ROOT__.$parent.'/'.$opt_subParent.$this->flags['filename'].'.'.$this->flags['extension']; +             $this->path = __ROOT__.$parent.'/'.$opt_subParent.$this->flags['filename'].'.'.$this->flags['extension'];             /* [7] On retourne si le fichier existe ou non             ==========================================================*/ -             return @file_get_contents( $this->path ) != false; +             return @file_get_contents( $this->path ) != false;         } @@ -489,15 +489,15 @@         */         public function getContent(){             // S'il y a eu une erreur en amont -             if( $this->error != ManagerError::Success ) -                 return false; // on retourne faux +             if( $this->error != ManagerError::Success ) +                 return false; // on retourne faux             // On inclut le contenu -             $content = file_get_contents($this->path); +             $content = file_get_contents($this->path);             // On retourne tout -             return str_replace( '</svg>', $this->stylesheet.'</svg>', $content ); +             return str_replace( '</svg>', $this->stylesheet.'</svg>', $content );         } @@ -517,7 +517,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/coverage/autoloader.php.html b/phpunit/coverage/autoloader.php.html index 0b66a5f..b5af751 100755 --- a/phpunit/coverage/autoloader.php.html +++ b/phpunit/coverage/autoloader.php.html @@ -214,7 +214,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/coverage/index.html b/phpunit/coverage/index.html index c7effcf..540684a 100755 --- a/phpunit/coverage/index.html +++ b/phpunit/coverage/index.html @@ -43,21 +43,21 @@ Total
-
- 67.51% covered (warning) +
+ 67.67% covered (warning)
-
67.51%
-
266 / 394
+
67.67%
+
270 / 399
-
- 47.73% covered (danger) +
+ 45.45% covered (danger)
-
47.73%
-
21 / 44
+
45.45%
+
20 / 44
11.11% covered (danger) @@ -127,21 +127,21 @@ Database.php
-
- 84.15% covered (warning) +
+ 83.33% covered (warning)
-
84.15%
-
69 / 82
-
-
- 57.14% covered (warning) +
83.33%
+
70 / 84
+
+
+ 42.86% covered (danger)
-
57.14%
-
4 / 7
+
42.86%
+
3 / 7
0.00% covered (danger) @@ -183,13 +183,13 @@ ModuleRequest.php
-
- 86.36% covered (warning) +
+ 86.81% covered (warning)
-
86.36%
-
76 / 88
+
86.81%
+
79 / 91
62.50% covered (warning) @@ -350,7 +350,7 @@ High: 90% to 100%

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/coverage/sessionManager.php.html b/phpunit/coverage/sessionManager.php.html index 1c8f21b..21c7d73 100755 --- a/phpunit/coverage/sessionManager.php.html +++ b/phpunit/coverage/sessionManager.php.html @@ -315,7 +315,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 9:37:55 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016.

diff --git a/phpunit/tests/ModuleRequest.php b/phpunit/tests/ModuleRequest.php index f7c5b31..2ee2515 100644 --- a/phpunit/tests/ModuleRequest.php +++ b/phpunit/tests/ModuleRequest.php @@ -165,6 +165,41 @@ $this->assertEquals( $ans->get('p1'), $params['p1'] ); $this->assertEquals( $ans->get('p2'), $params['p2'] ); } + + /* (4) Gestion des paramètres optionnels */ + public function testConstructOptionalParamGivenIncorrectType(){ + $_SESSION['permission'] = array(); + + $params = array( 'p1' => 'sometext', 'p2' => 'sometexttoo', 'p3' => -10 ); + + $req = new \manager\ModuleRequest( 'module/phpunitOptionalParams', $params ); + $this->assertEquals( $req->error, \manager\ManagerError::ParamError ); + } + public function testConstructOptionalParamGiven(){ + $_SESSION['permission'] = array(); + + $params = array( 'p1' => 'sometext', 'p2' => 'sometexttoo', 'p3' => 10 ); + + $req = new \manager\ModuleRequest( 'module/phpunitOptionalParams', $params ); + $this->assertEquals( $req->error, \manager\ManagerError::Success ); + } + public function testConstructOptionalParamNotGiven(){ + $_SESSION['permission'] = array(); + + $params = array( 'p1' => 'sometext', 'p2' => 'sometexttoo' ); + + $req = new \manager\ModuleRequest( 'module/phpunitOptionalParams', $params ); + $this->assertEquals( $req->error, \manager\ManagerError::Success ); + } + public function testConstructOptionalParamButRequiredMissing(){ + $_SESSION['permission'] = array(); + + $params = array( 'p1' => 'sometext', 'p3' => 10 ); + + $req = new \manager\ModuleRequest( 'module/phpunitOptionalParams', $params ); + $this->assertEquals( $req->error, \manager\ManagerError::ParamError ); + } + } From ad19c37b80b918dde11d12caa23503e68b2ae1ec Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 19:09:25 +0200 Subject: [PATCH 06/21] Corrections ModuleManager + modification des permissions possibles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ModuleRequest() param optionnel ou NULL Permissions de création possibles : 'admin' ou 'subject' (un admin peut être sujet quand même) --- config/modules.json | 19 +++++++++--------- manager/ModuleRequest.php | 2 +- manager/module/user.php | 7 ++++--- manager/repo/user.php | 21 +++++++++----------- phpunit/coverage/Database.php.html | 2 +- phpunit/coverage/ManagerError.php.html | 2 +- phpunit/coverage/ResourceDispatcher.php.html | 2 +- phpunit/coverage/autoloader.php.html | 2 +- phpunit/coverage/index.html | 2 +- phpunit/coverage/sessionManager.php.html | 2 +- view/js/settings.js | 4 ++-- 11 files changed, 32 insertions(+), 33 deletions(-) diff --git a/config/modules.json b/config/modules.json index 6128323..9d85660 100755 --- a/config/modules.json +++ b/config/modules.json @@ -69,11 +69,11 @@ "description": "Creation d'un nouvel utilisateur.", "permissions": ["admin"], "parameters": { - "login" : { "description": "Login de l'utilisateur, 30 caracteres maximum.", "type": "varchar(3,30)" }, - "password" : { "description": "Mot de passe de l'utilisateur.", "type": "text" }, - "mail" : { "description": "Adresse mail de l'utilisateur.", "type": "mail" }, - "reference" : { "description": "UID d'une personne d'un sondage, peut etre vide.", "type": "text" }, - "permissions": { "description": "Liste des permissions de l'utilisateur.", "type": "text" } + "login" : { "description": "Login de l'utilisateur, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "password" : { "description": "Mot de passe de l'utilisateur.", "type": "text" }, + "mail" : { "description": "Adresse mail de l'utilisateur.", "type": "mail" }, + "reference" : { "description": "UID d'une personne d'un sondage, peut etre vide.", "type": "text" }, + "permission" : { "description": "Permissions de l'utilisateur : 'admin' ou 'subject'", "type": "varchar(5,7)" } } }, @@ -164,16 +164,17 @@ "firstname" : { "description": "Prénom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, "lastname" : { "description": "Nom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, "id_facebook": { "description": "Id facebook du sujet (optionnel).", "type": "id", "optional": true }, - "number" : { "description": "Numéro de téléphone du sujet (optionnel).", "type": "text" } + "number" : { "description": "Numéro de téléphone du sujet (optionnel).", "type": "text", "optional": true } } }, - "remove": { - "description": "Suppression d'un utilisateur.", + "merge": { + "description": "Fusion de 2 sujets qui sont en fait la même personne.", "permissions": ["admin"], "parameters": { - "id_user": { "description": "UID de l'utilisateur", "type": "id" } + "id_source": { "description": "UID de l'utilisateur doublon", "type": "id" }, + "id_target": { "description": "UID de l'utilisateur déjà existant", "type": "id" } } } diff --git a/manager/ModuleRequest.php b/manager/ModuleRequest.php index bd8d15d..18ef64b 100755 --- a/manager/ModuleRequest.php +++ b/manager/ModuleRequest.php @@ -354,7 +354,7 @@ if( !isset($paramsdata['type']) ) continue; /* (4) Si le paramètre est optionnel et n'est pas donné */ - if( $optional && !isset($params[$name]) ){ + if( $optional && (!isset($params[$name]) || is_null($params[$name])) ){ // On le crée avec la valeur NULL $params[$name] = null; // On passe au paramètre suivant diff --git a/manager/module/user.php b/manager/module/user.php index 9daa673..2b8b0d4 100755 --- a/manager/module/user.php +++ b/manager/module/user.php @@ -142,11 +142,12 @@ =========================================================*/ $password = sessionManager::sha1($password); $reference = (is_numeric($reference)) ? (int) $reference : null; - $permissions = explode( ',', str_replace(' ', '', $permissions) ); + $permission = ($permission=='admin') ? 'admin' : 'subject'; + /* [1] Creation de l'utilisateur =========================================================*/ - $create = new Repo('user/create', array($login, $password, $mail, $reference, $permissions)); + $create = new Repo('user/create', array($login, $password, $mail, $reference, $permission)); $created_id = $create->answer(); // Si erreur de creation, on retourne une erreur @@ -171,7 +172,7 @@ */ public static function remove($params){ extract($params); - + /* [1] On verifie que l'utilisateur existe =========================================================*/ $exists = new Repo('user/getById', array($id_user)); diff --git a/manager/repo/user.php b/manager/repo/user.php index 6697a57..cd59f20 100755 --- a/manager/repo/user.php +++ b/manager/repo/user.php @@ -6,7 +6,7 @@ class user{ - + /* VERIFICATION DU LOGIN/PASSWORD D'UN UTILISATEUR * * @login Username ou Adresse mail de l'utilisateur @@ -122,19 +122,16 @@ * @return id_user Renvoie l'id de l'utilisateur cree ou FALSE si erreur * */ - public static function create($login, $password, $mail, $reference, $permissions){ + public static function create($login, $password, $mail, $reference, $permission){ /* [0] Verification et formattage des INPUT =========================================================*/ $checkInput = Database::check('sha1', $password); $checkInput = $checkInput && ( Database::check('id', $reference) || $reference === null ); - $checkInput = $checkInput && Database::check('array', $permissions); + $checkInput = $checkInput && in_array($permission, array('admin', 'subject')); // Si erreur en entree, on retourne FAUX if( !$checkInput ) return false; - // On formatte les permissions (array -> string) - $permissions = implode(',', $permissions); - /* [1] On verifie que le login/mail et reference sont uniques =========================================================*/ @@ -165,8 +162,8 @@ ':login' => $login, ':password' => $password, ':mail' => $mail, - ':permission' => $permissions - )); + ':permission' => $permission + )); /* (2) Si reference est defini */ }else{ @@ -178,8 +175,8 @@ ':password' => $password, ':mail' => $mail, ':reference' => (int) $reference, - ':permission' => $permissions - )); + ':permission' => $permission + )); } @@ -197,7 +194,7 @@ ':password' => $password, ':mail' => $mail, ':reference' => (int) $reference, - ':permission' => $permissions + ':permission' => $permission )); // On recupere l'id de l'utilisateur @@ -234,4 +231,4 @@ } -?> \ No newline at end of file +?> diff --git a/phpunit/coverage/Database.php.html b/phpunit/coverage/Database.php.html index 0211b51..7822670 100755 --- a/phpunit/coverage/Database.php.html +++ b/phpunit/coverage/Database.php.html @@ -565,7 +565,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/phpunit/coverage/ManagerError.php.html b/phpunit/coverage/ManagerError.php.html index 2f5ad2c..e1cc099 100755 --- a/phpunit/coverage/ManagerError.php.html +++ b/phpunit/coverage/ManagerError.php.html @@ -247,7 +247,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/phpunit/coverage/ResourceDispatcher.php.html b/phpunit/coverage/ResourceDispatcher.php.html index 96b3795..93bd24b 100755 --- a/phpunit/coverage/ResourceDispatcher.php.html +++ b/phpunit/coverage/ResourceDispatcher.php.html @@ -517,7 +517,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/phpunit/coverage/autoloader.php.html b/phpunit/coverage/autoloader.php.html index b5af751..c91c9c1 100755 --- a/phpunit/coverage/autoloader.php.html +++ b/phpunit/coverage/autoloader.php.html @@ -214,7 +214,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/phpunit/coverage/index.html b/phpunit/coverage/index.html index 540684a..c7cb0bc 100755 --- a/phpunit/coverage/index.html +++ b/phpunit/coverage/index.html @@ -350,7 +350,7 @@ High: 90% to 100%

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/phpunit/coverage/sessionManager.php.html b/phpunit/coverage/sessionManager.php.html index 21c7d73..5859ff4 100755 --- a/phpunit/coverage/sessionManager.php.html +++ b/phpunit/coverage/sessionManager.php.html @@ -315,7 +315,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 16:55:53 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016.

diff --git a/view/js/settings.js b/view/js/settings.js index 77c79bb..321fd46 100644 --- a/view/js/settings.js +++ b/view/js/settings.js @@ -136,7 +136,7 @@ var USERS = { 'password': USERS.add.password.value, 'mail': USERS.add.mail.value, 'reference': USERS.add.reference.value, - 'permissions': (USERS.add.isAdmin.checked) ? 'admin' : 'subject' + 'permission': (USERS.add.isAdmin.checked) ? 'admin' : 'subject' }; // On lance la requete @@ -182,4 +182,4 @@ for( var i = 0 ; i < USERS.remove.buttons.length ; i++ ){ }, false); -} \ No newline at end of file +} From a457737e892a6b7054cdfd3841d9681a80d8cc4c Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 19:33:36 +0200 Subject: [PATCH 07/21] =?UTF-8?q?subject/getById=20(module)=20impl=C3=A9me?= =?UTF-8?q?nt=C3=A9=20+=20ModuleRequest()=20cr=C3=A9e=20maintenant=20les?= =?UTF-8?q?=20param=C3=A8tres=20optionnels.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/modules.json | 2 +- config/repositories.json | 7 ++ manager/ModuleRequest.php | 3 +- manager/module/subject.php | 157 ++++++++++++++++++++++++++++++ manager/module/user.php | 2 +- manager/repo/subject.php | 192 +++++++++++++++++++++++++++++++++++++ 6 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 manager/module/subject.php create mode 100644 manager/repo/subject.php diff --git a/config/modules.json b/config/modules.json index 9d85660..bbc9a44 100755 --- a/config/modules.json +++ b/config/modules.json @@ -144,7 +144,7 @@ "description": "Retourne les informations d'un sujet.", "permissions": ["admin"], "parameters": { - "id_user": { "description": "UID du sujet recherche.", "type": "id" } + "id_subject": { "description": "UID du sujet recherche.", "type": "id" } } }, diff --git a/config/repositories.json b/config/repositories.json index 1ea2122..4d0ea8f 100755 --- a/config/repositories.json +++ b/config/repositories.json @@ -9,6 +9,13 @@ "remove" ], + "subject": [ + "getById", + "getAll", + "create", + "merge" + ], + "Personnes": [ "getById" ], diff --git a/manager/ModuleRequest.php b/manager/ModuleRequest.php index 18ef64b..ba89ec8 100755 --- a/manager/ModuleRequest.php +++ b/manager/ModuleRequest.php @@ -324,11 +324,12 @@ /* VERIFICATION DU TYPE DES PARAMETRES ENVOYES * * @params Tableau associatif contenant les parametres + * @params peut se voir rajouter les paramètres optionnels s'ils ne sont pas renseignés (initialisés à NULL) * * @return correct Retourne si oui ou non les parametres ont le bon type * */ - private function checkParams($params){ + private function checkParams(&$params){ /* [1] On verifie qu'il ne manque aucun parametre =========================================================*/ // Si @params n'est pas un tableau diff --git a/manager/module/subject.php b/manager/module/subject.php new file mode 100644 index 0000000..eaaabc7 --- /dev/null +++ b/manager/module/subject.php @@ -0,0 +1,157 @@ + UID du sujet en question + * + * @return subject Tableau contenant les informations du sujet + * + */ + public static function getById($params){ + extract($params); + + /* [1] On recupere les donnees du sujet + =========================================================*/ + $getUser = new Repo('subject/getById', array($id_subject)); + $subject_data = $getUser->answer(); + + // Si aucun utilisateur n'est trouve + if( $subject_data === false ) return array('ModuleError' => ManagerError::ModuleError); + + + /* [2] Gestion du retour + =========================================================*/ + return array( + 'ModuleError' => ManagerError::Success, + 'subject' => $subject_data + ); + } + + + + + /* RETOURNE LA LISTE DE TOUS LES SUJETS + * + * @return subjects Tableau contenant les informations de tous les utilisateurs + * + */ + public static function getAll(){ + /* [1] On recupere les donnees des utilisateurs + =========================================================*/ + $getUsers = new Repo('subject/getAll'); + $subjects_data = $getUsers->answer(); + + // Si aucun utilisateur n'est trouve + if( $subjects_data === false ) return array('ModuleError' => ManagerError::ModuleError); + + /* [2] Gestion du retour + =========================================================*/ + return array( + 'ModuleError' => ManagerError::Success, + 'subjects' => $subjects_data + ); + } + + + + + + /* CREATION D'UN SUJET + * + * @login Login (identifiant) du sujet + * @password Password du sujet + * @mail Adresse mail du sujet + * @reference Reference vers une Personne (sinon NULL) + * @permissions Liste des permissions du sujet + * + * @return id_subject Renvoie l'id du sujet cree + * + */ + public static function create($params){ + var_dump($params); + extract($params); + + /* [0] Verification et formattage des INPUT + =========================================================*/ + $password = sessionManager::sha1($password); + $reference = (is_numeric($reference)) ? (int) $reference : null; + $permission = ($permission=='admin') ? 'admin' : 'subject'; + + + /* [1] Creation du sujet + =========================================================*/ + $create = new Repo('subject/create', array($login, $password, $mail, $reference, $permission)); + $created_id = $create->answer(); + + // Si erreur de creation, on retourne une erreur + if( $created_id === false ) return array( 'ModuleError' => ManagerError::ModuleError ); + + /* [2] Gestion du retour + =========================================================*/ + return array( + 'ModuleError' => ManagerError::Success, + 'id_subject' => $created_id + ); + } + + + + + + /* SUPPRESSION D'UN SUJET + * + * @id_subject UID du sujet en question + * + */ + public static function remove($params){ + extract($params); + + /* [1] On verifie que le sujet existe + =========================================================*/ + $exists = new Repo('subject/getById', array($id_subject)); + $exists_status = $exists->answer(); + + // Si le sujet n'existe pas, on retourne une erreur + if( $exists_status === false ) return array( 'ModuleError' => ManagerError::ModuleError ); + + /* [2] Suppression du sujet + =========================================================*/ + $remove = new Repo('subject/remove', array($id_subject)); + $remove_status = $remove->answer(); + + + /* [3] On verifie que le sujet est bien supprime + =========================================================*/ + $removed = new Repo('subject/getById', array($id_subject)); + $removed_status = $removed->answer(); + + // Si le sujet n'existe pas, on retourne une erreur + if( $removed_status !== false ) return array( 'ModuleError' => ManagerError::ModuleError ); + + + /* [4] Gestion du retour + =========================================================*/ + return array( 'ModuleError' => ManagerError::Success ); + } + + // [x] "login", + // [x] "logout", + // [x] "getById", + // [x] "getAll", + // [x] "create", + // [ ] "remove", + + } + + +?> diff --git a/manager/module/user.php b/manager/module/user.php index 2b8b0d4..d6c04cd 100755 --- a/manager/module/user.php +++ b/manager/module/user.php @@ -71,7 +71,7 @@ /* [1] On recupere les donnees de l'utilisateur =========================================================*/ - $getUser = new Repo('user/getById', array($user_id)); + $getUser = new Repo('user/getById', array($id_user)); $user_data = $getUser->answer(); // Si aucun utilisateur n'est trouve diff --git a/manager/repo/subject.php b/manager/repo/subject.php new file mode 100644 index 0000000..9402b41 --- /dev/null +++ b/manager/repo/subject.php @@ -0,0 +1,192 @@ + UID du sujet en question + * + * @return subject Tableau contenant les donnees du sujet s'il existe sinon retourne FALSE + * + */ + public static function getById($id_subject){ + /* [1] On effectue la requete + =========================================================*/ + $getSubject = Database::getPDO()->prepare("SELECT idPersonne, pseudo, prenom, nom, id_facebook, telephone + FROM Personnes + WHERE idPersonne = :id_subject"); + $getSubject->execute(array( ':id_subject' => $id_subject )); + + + /* [2] On recupere le resultat de la requete + =========================================================*/ + $subjectData = $getSubject->fetch(); + + // Si l'utilisateur n'existe pas, on retourne FALSE + if( $subjectData === false ) return false; + + /* [3] Gestion du retour + =========================================================*/ + return Database::delNumeric( $subjectData, true ); + } + + + + + + /* RETOURNE LES DONNEES DE TOUS LES SUJETS + * + * @return subjects Tableau contenant les donnees des sujets, retourne FALSE si erreur + * + */ + public static function getAll(){ + /* [1] On effectue la requete + =========================================================*/ + $getSubjects = Database::getPDO()->query("SELECT idPersonne, pseudo, prenom, nom, id_facebook, telephone + FROM Personnes + ORDER BY idPersonne ASC"); + + + /* [2] On recupere le resultat de la requete + =========================================================*/ + $subjectsData = $getSubjects->fetchAll(); + + // Si l'utilisateur n'existe pas, on retourne FALSE + if( $subjectsData === false ) return false; + + /* [3] Gestion du retour + =========================================================*/ + return Database::delNumeric( $subjectsData ); + } + + + + + /* CREE UN SUJET + * + * @login Login (identifiant) du sujet + * @password Password du sujet + * @mail Adresse mail du sujet + * @reference Reference vers une Personne (sinon NULL) + * @permissions Liste des permissions du sujet + * + * @return id_subject Renvoie l'id du sujet cree ou FALSE si erreur + * + */ + public static function create($login, $password, $mail, $reference, $permission){ + /* [0] Verification et formattage des INPUT + =========================================================*/ + $checkInput = Database::check('sha1', $password); + $checkInput = $checkInput && ( Database::check('id', $reference) || $reference === null ); + $checkInput = $checkInput && in_array($permission, array('admin', 'subject')); + + // Si erreur en entree, on retourne FAUX + if( !$checkInput ) return false; + + + /* [1] On verifie que le login/mail et reference sont uniques + =========================================================*/ + $checkUnique = Database::getPDO()->prepare("SELECT id_subject + FROM subjects + WHERE login = :login + OR mail = :mail + OR ( reference = :reference AND reference is not NULL )"); + $checkUnique->execute(array( + ':login' => $login, + ':mail' => $mail, + ':reference' => $reference + )); + $unique = $checkUnique->fetch() === false; + + // Si un sujet a le meme LOGIN/MAIL ou REFERENCE, on retourne une erreur + if( !$unique ) return false; + + + /* [2] Creation du sujet + =========================================================*/ + /* (1) Si reference NULL */ + if( $reference == null ){ + + $create = Database::getPDO()->prepare("INSERT INTO subjects(id_subject, login, password, mail, reference, permission) + VALUES(DEFAULT, :login, :password, :mail, NULL, :permission)"); + $create->execute(array( + ':login' => $login, + ':password' => $password, + ':mail' => $mail, + ':permission' => $permission + )); + + /* (2) Si reference est defini */ + }else{ + + $create = Database::getPDO()->prepare("INSERT INTO subjects(id_subject, login, password, mail, reference, permission) + VALUES(DEFAULT, :login, :password, :mail, :reference, :permission)"); + $create->execute(array( + ':login' => $login, + ':password' => $password, + ':mail' => $mail, + ':reference' => (int) $reference, + ':permission' => $permission + )); + + } + + /* [3] Verification de la creation + recuperation id + =========================================================*/ + $checkCreate = Database::getPDO()->prepare("SELECT id_subject + FROM subjects + WHERE login = :login + AND password = :password + AND mail = :mail + AND ( reference = :reference OR reference is NULL ) + AND permission = :permission"); + $checkCreate->execute(array( + ':login' => $login, + ':password' => $password, + ':mail' => $mail, + ':reference' => (int) $reference, + ':permission' => $permission + )); + + // On recupere l'id du sujet + $id_subject = $checkCreate->fetch(); + + // Si erreur, on retourne FALSE + if( $id_subject === false ) return false; + + /* [4] Gestion du retour + =========================================================*/ + return $id_subject['id_subject']; + } + + + + + + + + + + /* SUPRESSION D'UN SUJET D'ID DONNE + * + * @id_subject UID du sujet en question + * + */ + public static function remove($id_subject){ + /* [1] On effectue la suppression + =========================================================*/ + $getSubject = Database::getPDO()->prepare("DELETE FROM subjects WHERE id_subject = :id_subject"); + $getSubject->execute(array( ':id_subject' => $id_subject )); + } + + } + + +?> From ec88d694270fe2e86a505d2c9cdedfd07ae1275e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Mon, 18 Apr 2016 22:45:55 +0200 Subject: [PATCH 08/21] =?UTF-8?q?Correction=20sociogram=20+=20avancement?= =?UTF-8?q?=20sur=20cr=C3=A9ation=20de=20'subject'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- automate.php | 8 +- config/modules.json | 22 +-- js/includes/sociogram.js | 18 +-- manager/Database.php | 26 +++ manager/module/call_log.php | 36 +---- manager/module/subject.php | 21 ++- manager/repo/subject.php | 52 +++--- manager/repo/user.php | 2 +- phpunit/coverage/Database.php.html | 161 ++++++++++++------- phpunit/coverage/ManagerError.php.html | 2 +- phpunit/coverage/ResourceDispatcher.php.html | 2 +- phpunit/coverage/autoloader.php.html | 2 +- phpunit/coverage/index.html | 34 ++-- phpunit/coverage/sessionManager.php.html | 2 +- 14 files changed, 215 insertions(+), 173 deletions(-) diff --git a/automate.php b/automate.php index a39ec9b..bbafc6c 100755 --- a/automate.php +++ b/automate.php @@ -50,7 +50,13 @@ echo $num.' <> '.$name.'
'; } - parseCallLog(); + // parseCallLog(); + + $username = ' '; + $firstname = ''; + $lastname = ''; + + var_dump( !!strlen($username.$firstname.$lastname) ); // Pseudo, prénom, ou nom, au moins un n'est pas vide diff --git a/config/modules.json b/config/modules.json index bbc9a44..c57a69d 100755 --- a/config/modules.json +++ b/config/modules.json @@ -52,7 +52,7 @@ "getById": { "description": "Retourne les informations d'un utilisateur.", "permissions": ["admin"], - "parameters": { + "parameters": { "id_user": { "description": "UID de l'utilisateur recherche.", "type": "id" } } }, @@ -69,11 +69,11 @@ "description": "Creation d'un nouvel utilisateur.", "permissions": ["admin"], "parameters": { - "login" : { "description": "Login de l'utilisateur, 30 caracteres maximum.", "type": "varchar(3,30)" }, - "password" : { "description": "Mot de passe de l'utilisateur.", "type": "text" }, - "mail" : { "description": "Adresse mail de l'utilisateur.", "type": "mail" }, - "reference" : { "description": "UID d'une personne d'un sondage, peut etre vide.", "type": "text" }, - "permission" : { "description": "Permissions de l'utilisateur : 'admin' ou 'subject'", "type": "varchar(5,7)" } + "login": { "description": "Login de l'utilisateur, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "password": { "description": "Mot de passe de l'utilisateur.", "type": "text" }, + "mail": { "description": "Adresse mail de l'utilisateur.", "type": "mail" }, + "reference": { "description": "UID d'une personne d'un sondage, peut etre vide.", "type": "text" }, + "permission": { "description": "Permissions de l'utilisateur : 'admin' ou 'subject'", "type": "varchar(5,7)" } } }, @@ -132,7 +132,7 @@ "description": "Creation d'un token de nom et de duree donnee", "permissions": ["admin"], "parameters": { - "name" : { "description": "Nom attribue au token", "type": "varchar(3,50)" }, + "name": { "description": "Nom attribue au token", "type": "varchar(3,50)" }, "duration": { "description": "Duree du token en nombre de jours", "type": "numeric" } } } @@ -160,11 +160,11 @@ "description": "Creation d'un nouveau sujet.", "permissions": ["admin"], "parameters": { - "username" : { "description": "Pseudo du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, - "firstname" : { "description": "Prénom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, - "lastname" : { "description": "Nom du sujet, 30 caracteres maximum.", "type": "varchar(3,30)" }, + "username" : { "description": "Pseudo du sujet, 30 caracteres maximum.", "type": "varchar(0,30)" }, + "firstname" : { "description": "Prénom du sujet, 30 caracteres maximum.", "type": "varchar(0,30)" }, + "lastname" : { "description": "Nom du sujet, 30 caracteres maximum.", "type": "varchar(0,30)" }, "id_facebook": { "description": "Id facebook du sujet (optionnel).", "type": "id", "optional": true }, - "number" : { "description": "Numéro de téléphone du sujet (optionnel).", "type": "text", "optional": true } + "number" : { "description": "Numéro de téléphone du sujet (optionnel).", "type": "number", "optional": true } } }, diff --git a/js/includes/sociogram.js b/js/includes/sociogram.js index 2a44e92..588fe3c 100644 --- a/js/includes/sociogram.js +++ b/js/includes/sociogram.js @@ -14,7 +14,7 @@ */ /* [1] Récupération du conteneur -=========================================================*/ +======================================*/ function sociogramClass(container){ this.container = container; this.log('sociogram created'); @@ -23,7 +23,7 @@ function sociogramClass(container){ /* [2] Construction de la classe -=========================================================*/ +======================================*/ sociogramClass.prototype = { container: this.container, sigma: null, @@ -122,7 +122,7 @@ sociogramClass.prototype.load = function(){ thisPtr.log(response); // Si erreur, on quitte - if( response.ModuleError !== 0 ) return; + if( response.ModuleError != 0 ) return; // On enregistre la réponse thisPtr.response = response; @@ -206,7 +206,7 @@ sociogramClass.prototype.nodeAt = function(x, y){ var minDistance = null; for( var nodeId in nodes ){ var distance = Math.sqrt( Math.pow(x-nodes[nodeId].x, 2) + Math.pow(y-nodes[nodeId].y, 2) ); - if( minDistance === null || distance < minDistance ) + if( minDistance == null || distance < minDistance ) minDistance = distance; } @@ -231,9 +231,9 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ var node = this.sigma.graph.nodes(nodeId); // Si le noeud est deja place, on ne fais rien - if( node.x !== 0 || node.y !== 0 ) return; + if( node.x != 0 || node.y != 0 ) return; - pos = (pos===null) ? {x: node.x, y: node.y} : pos; // On recupere la position + pos = (pos==null) ? {x: node.x, y: node.y} : pos; // On recupere la position // Tant que le noeud est trop proche d'un autre, on l'eloigne // UNIQUEMENT si alone n'est pas NULL @@ -278,7 +278,7 @@ sociogramClass.prototype.arrange = function(nodeId, pos, alone){ for( neighborId in neighbors ){ var current = this.sigma.graph.nodes(neighborId); // Si n'est pas deja positionne - if( current.x === 0 && current.y === 0 ){ + if( current.x == 0 && current.y == 0 ){ // On cherche un angle tant qu'il est pas trop pres d'un deja pris var angle, alreadyUsed = false; do{ @@ -328,7 +328,7 @@ sociogramClass.prototype.overload.nodeNeighbors = function(nodeId){ var subneighbors = this.allNeighborsIndex[stack[0]]; for( var subId in subneighbors ) // Si le voisin est pas deja dans la liste/pile, on l'ajoute a la liste des voisins - if( neighbors[subId] === null ){ + if( neighbors[subId] == null ){ stack.push(subId); // On ajoute a la pile neighbors[subId] = subneighbors[subId]; // On ajoute a la liste complete } @@ -455,7 +455,7 @@ sociogramClass.prototype.bindings.clickNode = function(thisPtr, e){ neighborNodes[nodeId] = e.data.node; // on ajoute le noeud clique thisPtr.sigma.graph.nodes().forEach(function(n) { - if( neighborNodes[n.id] !== null ) n.color = n.originalColor; + if( neighborNodes[n.id] != null ) n.color = n.originalColor; else n.color = '#eee'; }); diff --git a/manager/Database.php b/manager/Database.php index 7c63de4..53683dc 100755 --- a/manager/Database.php +++ b/manager/Database.php @@ -262,6 +262,32 @@ } + + + + /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE + * + * @number Numéro de téléphone en +336/336/06/0336/00336 + * + * @return formatted Numéro formatté (06), on FALSE si erreur + * + */ + public static function formatNumber($number){ + // On met en quel que soit le type + $number = (string) $number; + + // On supprime tous les espaces + $number = str_replace(' ', '', $number); + + // On formatte le numéro + if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) + $number = '0'.$m[1]; + + // On retourne le numéro formatté + return $number; + } + + //////////////////////////////////// // _ _ // __| | __ _| |_ ___ ___ diff --git a/manager/module/call_log.php b/manager/module/call_log.php index 71bd603..eb46446 100644 --- a/manager/module/call_log.php +++ b/manager/module/call_log.php @@ -9,34 +9,6 @@ class call_log{ - /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE - * - * @number Numéro de téléphone en +336/336/06 - * - * @return formatted Numéro formatté (06), on FALSE si erreur - * - */ - private static function formatNumber($number){ - // On met en quel que soit le type - $number = (string) $number; - - // On supprime tous les espaces - $number = str_replace(' ', '', $number); - - // On formatte le numéro - if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) - $number = '0'.$m[1]; - - // On retourne le numéro formatté - return $number; - } - - - - - - - /* DESERIALISATION D'UN JOURNAL D'APPEL * * @content Le contenu du journal d'appel a deserialiser @@ -51,7 +23,7 @@ extract($params); // On formatte le numéro de téléphone - $phone_number = self::formatNumber($phone_number); + $phone_number = Database::formatNumber($phone_number); /* [1] On parse/récupère le xml =========================================================*/ @@ -68,7 +40,7 @@ foreach($xml->Item as $log){ /* (1) On formatte le numéro */ - $number = self::formatNumber($log['Number']); + $number = Database::formatNumber($log['Number']); /* (2) On enregistre le contact dans l'annuaire s'il y est pas déjà */ if( !isset($phone_directory[$number]) ) @@ -76,8 +48,8 @@ /* (3) On complète le log */ $phone_log = array( - 'source' => ($log['Direction']=='INCOMING') ? $number : self::formatNumber($phone_number), - 'target' => ($log['Direction']=='INCOMING') ? self::formatNumber($phone_number) : $number, + 'source' => ($log['Direction']=='INCOMING') ? $number : Database::formatNumber($phone_number), + 'target' => ($log['Direction']=='INCOMING') ? Database::formatNumber($phone_number) : $number, 'type' => strtolower($log['Type']), 'date' => strtotime($log['Date']), 'duration' => (int) $log['Duration'] diff --git a/manager/module/subject.php b/manager/module/subject.php index eaaabc7..ce94c1a 100644 --- a/manager/module/subject.php +++ b/manager/module/subject.php @@ -68,29 +68,26 @@ /* CREATION D'UN SUJET * - * @login Login (identifiant) du sujet - * @password Password du sujet - * @mail Adresse mail du sujet - * @reference Reference vers une Personne (sinon NULL) - * @permissions Liste des permissions du sujet + * @username Pseudo du sujet + * @firstname Prénom du sujet + * @lastname Nom du sujet + * @id_facebook Id facebook du sujet (optionnel) + * @number Numéro de téléphone du sujet (optionnel) * * @return id_subject Renvoie l'id du sujet cree * */ public static function create($params){ - var_dump($params); extract($params); /* [0] Verification et formattage des INPUT =========================================================*/ - $password = sessionManager::sha1($password); - $reference = (is_numeric($reference)) ? (int) $reference : null; - $permission = ($permission=='admin') ? 'admin' : 'subject'; - + $id_facebook = !is_null($id_facebook) ? (int) $id_facebook : null; + $number = !is_null($number) ? Database::formatNumber($number) : null; /* [1] Creation du sujet =========================================================*/ - $create = new Repo('subject/create', array($login, $password, $mail, $reference, $permission)); + $create = new Repo('subject/create', array($username, $firstname, $lastname, $id_facebook, $number)); $created_id = $create->answer(); // Si erreur de creation, on retourne une erreur @@ -100,7 +97,7 @@ =========================================================*/ return array( 'ModuleError' => ManagerError::Success, - 'id_subject' => $created_id + 'id_subject' => $created_id ); } diff --git a/manager/repo/subject.php b/manager/repo/subject.php index 9402b41..0b364f9 100644 --- a/manager/repo/subject.php +++ b/manager/repo/subject.php @@ -71,47 +71,41 @@ /* CREE UN SUJET * - * @login Login (identifiant) du sujet - * @password Password du sujet - * @mail Adresse mail du sujet - * @reference Reference vers une Personne (sinon NULL) - * @permissions Liste des permissions du sujet + * @username Pseudo du sujet + * @firstname Prénom du sujet + * @lastname Nom du sujet + * @id_facebook Id facebook du sujet (optionnel) + * @number Numéro de téléphone du sujet (optionnel) * * @return id_subject Renvoie l'id du sujet cree ou FALSE si erreur * */ - public static function create($login, $password, $mail, $reference, $permission){ + public static function create($username, $firstname, $lastname, $id_facebook, $number){ /* [0] Verification et formattage des INPUT =========================================================*/ - $checkInput = Database::check('sha1', $password); - $checkInput = $checkInput && ( Database::check('id', $reference) || $reference === null ); - $checkInput = $checkInput && in_array($permission, array('admin', 'subject')); + $checkInput = Database::check('varchar(0,30)', $username); + $checkInput = $checkInput && Database::check('varchar(0,30)', $firstname); + $checkInput = $checkInput && Database::check('varchar(0,30)', $lastname); + $checkInput = $checkInput && !!strlen($username.$firstname.$lastname); // Pseudo, prénom, ou nom, au moins un n'est pas vide + $checkInput = $checkInput && ( Database::check('id', $id_facebook) || is_null($id_facebook) ); + $checkInput = $checkInput && ( Database::check('number', $number) || is_null($number) ); // Si erreur en entree, on retourne FAUX if( !$checkInput ) return false; - - /* [1] On verifie que le login/mail et reference sont uniques + /* [1] On écrit la requête =========================================================*/ - $checkUnique = Database::getPDO()->prepare("SELECT id_subject - FROM subjects - WHERE login = :login - OR mail = :mail - OR ( reference = :reference AND reference is not NULL )"); - $checkUnique->execute(array( - ':login' => $login, - ':mail' => $mail, - ':reference' => $reference - )); - $unique = $checkUnique->fetch() === false; + $request_create = 'INSERT INTO Personnes(idPersonne, pseudo, nom, prenom, id_facebook, telephone) '; + $request_create .= 'VALUES ('; + $request_create .= 'DEFAULT, '; // idPersone + $request_create .= strlen($username) ? ':pseudo, ' : 'NULL, '; // pseudo + $request_create .= strlen($lastname) ? ':nom, ' : 'NULL, '; // nom + $request_create .= strlen($firstname) ? ':prenom, ' : 'NULL, '; // prenom + $request_create .= !is_null($id_facebook) ? ':id_facebook, ' : 'NULL, '; // Id facebook + $request_create .= !is_null($number) ? ':number, ' : 'NULL, '; // Numéro de tél + $request_create .= ')'; - // Si un sujet a le meme LOGIN/MAIL ou REFERENCE, on retourne une erreur - if( !$unique ) return false; - - - /* [2] Creation du sujet - =========================================================*/ - /* (1) Si reference NULL */ + /* (1) Si id_facebook NULL */ if( $reference == null ){ $create = Database::getPDO()->prepare("INSERT INTO subjects(id_subject, login, password, mail, reference, permission) diff --git a/manager/repo/user.php b/manager/repo/user.php index cd59f20..71a5119 100755 --- a/manager/repo/user.php +++ b/manager/repo/user.php @@ -126,7 +126,7 @@ /* [0] Verification et formattage des INPUT =========================================================*/ $checkInput = Database::check('sha1', $password); - $checkInput = $checkInput && ( Database::check('id', $reference) || $reference === null ); + $checkInput = $checkInput && ( Database::check('id', $reference) || is_null($reference) ); $checkInput = $checkInput && in_array($permission, array('admin', 'subject')); // Si erreur en entree, on retourne FAUX diff --git a/phpunit/coverage/Database.php.html b/phpunit/coverage/Database.php.html index 7822670..8f67e86 100755 --- a/phpunit/coverage/Database.php.html +++ b/phpunit/coverage/Database.php.html @@ -51,22 +51,22 @@
0.00%
0 / 1
-
- 42.86% covered (danger) +
+ 37.50% covered (danger)
-
42.86%
-
3 / 7
+
37.50%
+
3 / 8
CRAP
-
- 83.33% covered (warning) +
+ 78.65% covered (warning)
-
83.33%
-
70 / 84
+
78.65%
+
70 / 89
@@ -80,22 +80,22 @@
0.00%
0 / 1
-
- 42.86% covered (danger) +
+ 37.50% covered (danger)
-
42.86%
-
3 / 7
- 63.04 +
37.50%
+
3 / 8
+ 80.33
-
- 83.33% covered (warning) +
+ 78.65% covered (warning)
-
83.33%
-
70 / 84
+
78.65%
+
70 / 89
@@ -225,7 +225,28 @@ -  frDate +  formatNumber +
+
+ 0.00% covered (danger) +
+
+ +
0.00%
+
0 / 1
+ 6 +
+
+ 0.00% covered (danger) +
+
+ +
0.00%
+
0 / 5
+ + + +  frDate
0.00% covered (danger) @@ -514,45 +535,71 @@         } -         //////////////////////////////////// -         //      _       _ -         //   __| | __ _| |_ ___  ___ -         //  / _` |/ _` | __/ _ \/ __| -         // | (_| | (_| | ||  __/\__ \ -         //  \__,_|\__,_|\__\___||___/ -         // -         //////////////////////////////////// -         // 1) Convertis une date en en francais explicite -         public static function frDate($date){ -             /* [1] On definit les traductions -             =========================================================*/ -             // Jours de la semaine -             $days   = array("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"); -             // Mois de l'annee -             $months = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"); + + + +         /* FONCTION QUI FORMATTE UN NUMÉRO DE TÉLÉPHONE +         * +         * @number<String>                                         Numéro de téléphone en +336/336/06/0336/00336 +         * +         * @return formatted<String>                             Numéro formatté (06), on FALSE si erreur +         * +         */ +         public static function formatNumber($number){ +             // On met en <string> quel que soit le type +             $number = (string) $number; + +             // On supprime tous les espaces +             $number = str_replace(' ', '', $number); -             /* [2] On recupere le timestamp et les indices -             =========================================================*/ -             $time = strtotime($date); // timestamp -             $daynum = intval( date('N', $time)-1 ); // jour dans la semaine -             $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee - - -             /* [3] On recupere les infos independemment -             =========================================================*/ -             $result = array( -                 $days[$daynum],     // nom de jour -                 date('j', $time),   // jour du mois -                 $months[$monthnum], // nom du mois -                 date('Y', $time),   // annee -             ); - - -             return implode(" ", $result); -         } - -     } - ?> +             // On formatte le numéro +             if( preg_match("/^(?:\+33|0?0?33|0)(.+)/", $number, $m) ) +                 $number = '0'.$m[1]; + +             // On retourne le numéro formatté +             return $number; +         } + + +         //////////////////////////////////// +         //      _       _ +         //   __| | __ _| |_ ___  ___ +         //  / _` |/ _` | __/ _ \/ __| +         // | (_| | (_| | ||  __/\__ \ +         //  \__,_|\__,_|\__\___||___/ +         // +         //////////////////////////////////// +         // 1) Convertis une date en en francais explicite +         public static function frDate($date){ +             /* [1] On definit les traductions +             =========================================================*/ +             // Jours de la semaine +             $days   = array("Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche"); +             // Mois de l'annee +             $months = array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"); + +             /* [2] On recupere le timestamp et les indices +             =========================================================*/ +             $time = strtotime($date); // timestamp +             $daynum = intval( date('N', $time)-1 ); // jour dans la semaine +             $monthnum = intval( date('n', $time)-1 ); // numero du mois dans l'annee + + +             /* [3] On recupere les infos independemment +             =========================================================*/ +             $result = array( +                 $days[$daynum],     // nom de jour +                 date('j', $time),   // jour du mois +                 $months[$monthnum], // nom du mois +                 date('Y', $time),   // annee +             ); + + +             return implode(" ", $result); +         } + +     } + ?> @@ -565,7 +612,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

diff --git a/phpunit/coverage/ManagerError.php.html b/phpunit/coverage/ManagerError.php.html index e1cc099..6051d52 100755 --- a/phpunit/coverage/ManagerError.php.html +++ b/phpunit/coverage/ManagerError.php.html @@ -247,7 +247,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

diff --git a/phpunit/coverage/ResourceDispatcher.php.html b/phpunit/coverage/ResourceDispatcher.php.html index 93bd24b..9bb2f42 100755 --- a/phpunit/coverage/ResourceDispatcher.php.html +++ b/phpunit/coverage/ResourceDispatcher.php.html @@ -517,7 +517,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

diff --git a/phpunit/coverage/autoloader.php.html b/phpunit/coverage/autoloader.php.html index c91c9c1..eb4efed 100755 --- a/phpunit/coverage/autoloader.php.html +++ b/phpunit/coverage/autoloader.php.html @@ -214,7 +214,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

diff --git a/phpunit/coverage/index.html b/phpunit/coverage/index.html index c7cb0bc..fc1de51 100755 --- a/phpunit/coverage/index.html +++ b/phpunit/coverage/index.html @@ -43,21 +43,21 @@ Total
-
- 67.67% covered (warning) +
+ 66.83% covered (warning)
-
67.67%
-
270 / 399
+
66.83%
+
270 / 404
-
- 45.45% covered (danger) +
+ 44.44% covered (danger)
-
45.45%
-
20 / 44
+
44.44%
+
20 / 45
11.11% covered (danger) @@ -127,21 +127,21 @@ Database.php
-
- 83.33% covered (warning) +
+ 78.65% covered (warning)
-
83.33%
-
70 / 84
+
78.65%
+
70 / 89
-
- 42.86% covered (danger) +
+ 37.50% covered (danger)
-
42.86%
-
3 / 7
+
37.50%
+
3 / 8
0.00% covered (danger) @@ -350,7 +350,7 @@ High: 90% to 100%

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

diff --git a/phpunit/coverage/sessionManager.php.html b/phpunit/coverage/sessionManager.php.html index 5859ff4..f0d06d6 100755 --- a/phpunit/coverage/sessionManager.php.html +++ b/phpunit/coverage/sessionManager.php.html @@ -315,7 +315,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 17:06:21 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016.

From b68a02d64f029d334a7b4226abbc1231c6ea1430 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 19 Apr 2016 11:14:28 +0200 Subject: [PATCH 09/21] getters dynamiques (statiques) pour les repos!! [magic method] --- automate.php | 10 +++---- manager/repo/user.php | 64 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/automate.php b/automate.php index bbafc6c..6707538 100755 --- a/automate.php +++ b/automate.php @@ -52,12 +52,6 @@ // parseCallLog(); - $username = ' '; - $firstname = ''; - $lastname = ''; - - var_dump( !!strlen($username.$firstname.$lastname) ); // Pseudo, prénom, ou nom, au moins un n'est pas vide - /* () Test du client de l'API generique */ @@ -69,4 +63,8 @@ // var_dump($response); + + + var_dump( \manager\repo\user::getByMail('B@gmail.com') ); + ?> diff --git a/manager/repo/user.php b/manager/repo/user.php index 71a5119..681a7ca 100755 --- a/manager/repo/user.php +++ b/manager/repo/user.php @@ -6,6 +6,59 @@ class user{ + private static $table_name = 'users'; + private static $columns = null; + + // Getters dynamiques + public static function __callStatic($method, $args){ + /* [0] Si les colonnes valides ne sont pas chargées, on les charges + =========================================================*/ + if( is_null(self::$columns) ){ + $getColumns = Database::getPDO()->query('SHOW COLUMNS FROM '.self::$table_name); + $cols = $getColumns->fetchAll(); + + self::$columns = array(); + + // On ajoute la liste des colonnes + foreach($cols as $column) + array_push(self::$columns, $column['Field']); + } + + /* [1] On vérifie que la méthode est 'getX', avec X une chaine + =========================================================*/ + // Si c'est pas le bon format, on retourne une erreur + if( !preg_match('/^getBy(\w+)$/', $method, $matches) ) return false; + + /* [2] On vérifie que la valeur après 'get' est dans self::$columns + =========================================================*/ + $columnName = strtolower($matches[1]); + + $getAll = $columnName == 'all'; // Si 'getAll' + $getSomething = count($args) > 0 && in_array($columnName, self::$columns); // Si 'getX', et 'X' dans la liste des colonnes + + // Si ni 'getAll' ni 'getSomething' -> erreur + if( !$getAll && !$getSomething ) return false; + + /* [3] On rédige la requête + =========================================================*/ + $getRequestString = 'SELECT * FROM '.self::$table_name; + // Si c'est 'getSomething', on ajoute une condition + if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; + + $getRequest = Database::getPDO()->prepare($getRequestString); + + /* [4] On exécute la requête + =========================================================*/ + // Si 'getSomething', on ajoute le champ + $getRequest->execute(array( + ':value' => $getSomething ? $args[0] : null + )); + + /* [5] On récupère le résultat + =========================================================*/ + return Database::delNumeric( $getRequest->fetchAll() ); + } + /* VERIFICATION DU LOGIN/PASSWORD D'UN UTILISATEUR * @@ -59,6 +112,10 @@ * */ public static function getById($id_user){ + /* [0] On formatte et vérifie les INPUT + =========================================================*/ + if( !Database::check('id', $id_user) ) return false; + /* [1] On effectue la requete =========================================================*/ $getUser = Database::getPDO()->prepare("SELECT id_user, login, mail, permission @@ -126,6 +183,8 @@ /* [0] Verification et formattage des INPUT =========================================================*/ $checkInput = Database::check('sha1', $password); + $checkInput = $checkInput && Database::check('varchar(3, 30)', $login); + $checkInput = $checkInput && Database::check('mail', $mail); $checkInput = $checkInput && ( Database::check('id', $reference) || is_null($reference) ); $checkInput = $checkInput && in_array($permission, array('admin', 'subject')); @@ -145,10 +204,9 @@ ':mail' => $mail, ':reference' => $reference )); - $unique = $checkUnique->fetch() === false; - // Si un utilisateur a le meme LOGIN/MAIL ou REFERENCE, on retourne une erreur - if( !$unique ) return false; + // Si un utilisateur a le meme LOGIN/MAIL ou REFERENCE qu'un autre, on retourne une erreur + if( $checkUnique->fetch() !== false ) return false; /* [2] Creation de l'utilisateur From bd7eaf02a55e07b1ad0fe729727483efc84824d3 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 19 Apr 2016 13:44:41 +0200 Subject: [PATCH 10/21] Correction et parent pour tous les repos (pour le getter dynamique) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correction de l'héritage statique --- automate.php | 2 +- manager/Repo.php | 24 +-- manager/repo/Personnes.php | 69 -------- manager/repo/machine.php | 337 ------------------------------------ manager/repo/parentRepo.php | 76 ++++++++ manager/repo/subject.php | 4 +- manager/repo/token.php | 12 +- manager/repo/user.php | 55 +----- 8 files changed, 102 insertions(+), 477 deletions(-) delete mode 100755 manager/repo/Personnes.php delete mode 100755 manager/repo/machine.php create mode 100644 manager/repo/parentRepo.php diff --git a/automate.php b/automate.php index 6707538..a46fcb2 100755 --- a/automate.php +++ b/automate.php @@ -64,7 +64,7 @@ // var_dump($response); - var_dump( \manager\repo\user::getByMail('B@gmail.com') ); + var_dump( \manager\repo\subject::getByPseudo('jeannot') ); ?> diff --git a/manager/Repo.php b/manager/Repo.php index 3d54c0b..a87edd8 100755 --- a/manager/Repo.php +++ b/manager/Repo.php @@ -1,18 +1,18 @@ -repositories = json_decode( ResourceDispatcher::getResource(self::$config_path), true ); - + // Gestion de l'erreur de parsage if( $this->repositories == null ){ $this->error = ManagerError::ParsingFailed; @@ -72,7 +72,7 @@ } // Type de @data (optionnel) - $data = (is_array($data)) ? $data : array(); + $data = (is_array($data)) ? $data : array(); /* [2] Verification du chemin (existence repo+methode) @@ -165,7 +165,7 @@ $this->error = ManagerError::UnknownMethod; return false; // On retourne FALSE, si erreur } - + /* [4] Enregistrement du chemin et renvoi de SUCCESS @@ -194,4 +194,4 @@ } -?> \ No newline at end of file +?> diff --git a/manager/repo/Personnes.php b/manager/repo/Personnes.php deleted file mode 100755 index a47fa6c..0000000 --- a/manager/repo/Personnes.php +++ /dev/null @@ -1,69 +0,0 @@ - portage des donnees) - * - merge(idA, idB) - * - * 4. Gestion de creation - * - create(pseudo, nom, prenom, facebook, telephone) - * - * - */ - - - /* RENVOIE LES DONNEES D'UN UTILISATEUR D'UID DONNE - * - * @id_personne UID de la personne en question - * - * @return personne Tableau associatif contenant les informations utiles de la personne - * @return FALSE Si une erreur occure ou qu'aucune personne n'est trouvee, retourne FALSE - * - */ - public static function getById($id_personne=null){ - /* [0] Verification des INPUT - =========================================================*/ - if( !Database::check('id', $id_personne) ) return false; - - /* [1] On prepare et execute la requete - =========================================================*/ - $request = Database::getPDO()->prepare("SELECT idPersonne as id, pseudo, nom, prenom, id_facebook, telephone - FROM Personnes - WHERE idPersonne = :uid"); - $request->execute(array( - ':uid' => $id_personne - )); - - - /* [2] On recupere le resultat - =========================================================*/ - // si aucun resultat, on retourne FALSE - if( ($personne=$request->fetch()) === false ) return false; - - - /* [3] On retourne les donnees - =========================================================*/ - return Database::delNumeric( $personne, true ); - } - - - - - - - } - - -?> \ No newline at end of file diff --git a/manager/repo/machine.php b/manager/repo/machine.php deleted file mode 100755 index 2255185..0000000 --- a/manager/repo/machine.php +++ /dev/null @@ -1,337 +0,0 @@ - Code de la machine - * @name Nom de la machine - * - * @return id_machine Renvoie l'UID de la machine cree - * Renvoie FALSE si une erreur occure - * - */ - public static function create($code, $name){ - /* [1] Verification de l'unicite de code+name - =========================================================*/ - $check_unique = ( self::getByCode($code) === false ); - $check_unique = $check_unique && ( self::getByName($name) === false ); - - // Si une machine a deja ce code/nom, on renvoie une erreur - if( !$check_unique ) - return false; - - - /* [2] Creation de la machine - =========================================================*/ - $insert_machine = Database::getPDO()->prepare("INSERT INTO machine(id_machine, code, name) - VALUES(DEFAULT, :code, :name)"); - $insert_machine->execute(array( - ':code' => $code, - ':name' => $name - )); - - /* [3] On retourne l'id_machine ou FALSE si erreur - =========================================================*/ - $check_machine = self::getByCode($code); - - // Si n'existe pas on retourne FALSE - if( $check_machine === false ) - return false; - - // Sinon, on retourne son id - return $check_machine['id_machine']; - - } - - - - - - /* RENVOIE UNE LISTE DE MACHINE EN FONCTION D'UN MOT CLE - * - * @keyword Element de recherche - * - * @return machines Retourne les machines trouvees - * - */ - public static function search($keyword){ - // On recupere les donnees - $searchmachines = Database::getPDO()->query("SELECT * FROM machine - WHERE code LIKE '%".$keyword."%' - OR name LIKE '%".$keyword."%' - "); - - return Database::delNumeric( $searchmachines->fetchAll() ); - } - - - - - - - - /* RENVOIE LA LISTE DE TOUTES LES MACHINES - * - * @return machine Liste des machines de la BDD - * - */ - public static function getAll(){ - // On ecrit la requete - $request = Database::getPDO()->query("SELECT * FROM machine ORDER BY name"); - - // On recupere le resultat - $answer = $request->fetchAll(); - - // On retourne en supprimant les indices numeriques - return Database::delNumeric( $answer ); - } - - - - - - - - - /* RENVOIE LA MACHINE D'ID DONNE - * - * @id Id de la machine en question - * - * @return machine Renvoie la machine d'id donne si existe - * @return error Retourne FALSE si aucun resultat - * - */ - public static function getById($id){ - // On ecrit la requete - $request = Database::getPDO()->prepare("SELECT * FROM machine - WHERE id_machine = :id"); - - // On execute la requete - $request->execute(array( - ':id' => $id - )); - - // On recupere 1 seule machine - $answer = $request->fetch(); - - // Gestion d'erreur -> aucun resultat - if( $answer === false ) - return false; - - // On retourne en supprimant les indices numeriques - return Database::delNumeric( $answer, true ); - } - - - - - - - - - /* RENVOIE LA MACHINE DE CODE DONNE - * - * @code Code de la machine en question - * - * @return machine Renvoie la machine de code donne si existe - * @return error Retourne FALSE si aucun resultat - * - */ - public static function getByCode($code){ - // On ecrit la requete - $request = Database::getPDO()->prepare("SELECT * FROM machine - WHERE code = :code"); - - - // On execute la requete - $request->execute(array( - ':code' => $code - )); - - // On recupere 1 seule machine - $answer = $request->fetch(); - - // Gestion d'erreur -> aucun resultat - if( $answer === false ) - return false; - - // On retourne en supprimant les indices numeriques - return Database::delNumeric( $answer, true ); - - } - - - - - - - - - /* RENVOIE LA MACHINE DE NOM DONNE - * - * @name Nom de la machine en question - * - * @return machine Renvoie la machine de nom donne si existe - * @return error Retourne FALSE si aucun resultat - * - */ - public static function getByName($name){ - // On ecrit la requete - $request = Database::getPDO()->prepare("SELECT * FROM machine - WHERE name = :name"); - - - // On execute la requete - $request->execute(array( - ':name' => $name - )); - - // On recupere 1 seule machine - $answer = $request->fetch(); - - // Gestion d'erreur -> aucun resultat - if( $answer === false ) - return false; - - // On retourne en supprimant les indices numeriques - return Database::delNumeric( $answer, true ); - - } - - - - - - - - - /* RENVOIE LES GROUPES AUQUEL APPARTIENT UNE MACHINE DONNEE - * - * @id_machine UID de la machine en question - * - * @return clusters Retourne la liste des groupes auquel appartient la machine - * - */ - public static function getClusters($id_machine){ - /* [1] On redige/execute la requete - =========================================================*/ - $get_clusters = Database::getPDO()->prepare("SELECT c.* FROM cluster as c, cluster_merge as cm - WHERE cm.id_cluster = c.id_cluster - AND cm.id_entity = :id_machine - AND cm.class = :class - ORDER BY c.id_cluster"); - $get_clusters->execute(array( - ':id_machine' => $id_machine, - ':class' => clusterRepo::MACHINE_CLASS - )); - - /* [2] On retourne la liste des groupes - =========================================================*/ - return Database::delNumeric( $get_clusters->fetchAll() ); - } - - - - - - - - - /* MODIFICATION D'UNE MACHINE DONNEE - * - * @id_machine UID de la machine - * @code Code RFID de la machine - * @name Identifiant l'utilisateur - * - * @return status Renvoie si oui ou non tout s'est bien passe - * - */ - public static function edit($id_machine=null, $code=null, $name=null){ - /* [1] Verification de l'unicite de code+name (si differents) - =========================================================*/ - // On recupere les machine ayant le meme code ou name (si existent) - $getbycode = self::getByCode($code); - $getbyname = self::getByName($name); - - $check_unique = is_array($getbycode) && $getbycode['id_machine'] == $id_machine || !is_array($getbycode); - $check_unique = $check_unique && is_array($getbyname) && $getbyname['id_machine'] == $id_machine || !is_array($getbyname); - - // Si un utilisateur a deja ce code ou ce name (sauf lui), on renvoie une erreur - if( !$check_unique ) - return false; - - /* [2] Modification de la machine - =========================================================*/ - $edit_machine = Database::getPDO()->prepare("UPDATE machine - SET code = :code, - name = :name - WHERE id_machine = :id_machine"); - $edit_machine->execute(array( - ':code' => $code, - ':name' => $name, - ':id_machine' => $id_machine - )); - - - - /* [3] On retourne si tout a ete modifie, si erreur - =========================================================*/ - $check_machine = self::getById($id_machine); - - $checker = $check_machine['id_machine'] == $id_machine; - $checker = $checker && $check_machine['code'] == $code; - $checker = $checker && $check_machine['name'] == $name; - - // On retourne l'etat de la modification - return $checker; - } - - - - - - - - - /* SUPPRIME UNE MACHINE DONNE - * - * @id_machine UID de la machine en question - * - * @return status Retourne si oui ou non la machine a bien ete supprime - * - */ - public static function delete($id_machine){ - /* [1] On redige/execute la requete - =========================================================*/ - $delete_machine = Database::getPDO()->prepare("DELETE FROM machine WHERE id_machine = :id_machine"); - $delete_machine->execute(array( - ':id_machine' => $id_machine - )); - - - /* [2] On verifie que la machine n'existe plus - =========================================================*/ - return ( self::getById($id_machine) === false ); - } - - - - - - - - - - - - - - } - - -?> \ No newline at end of file diff --git a/manager/repo/parentRepo.php b/manager/repo/parentRepo.php new file mode 100644 index 0000000..067c909 --- /dev/null +++ b/manager/repo/parentRepo.php @@ -0,0 +1,76 @@ + Nom du getter du type 'getAll' ou 'getX' avec 'X' une colonne de la table en question + * @args Liste des arguments, $args[0] est la valeur du getter (sauf pour 'getAll') + * + * @return lines Retourne le résultat du fetchAll() + * + */ + public static function __callStatic($method, $args){ + // Si static::table_name() NULL + if( is_null(static::table_name()) ) return false; + + /* [0] On charge la liste des colonnes de la table + =========================================================*/ + $getColumns = Database::getPDO()->query('SHOW COLUMNS FROM '.static::table_name()); + $cols = $getColumns->fetchAll(); + + $table_columns = array(); + + // On ajoute la liste des colonnes + foreach($cols as $column) + array_push($table_columns, $column['Field']); + + + /* [1] On vérifie que la méthode est 'getX', avec X une chaine + =========================================================*/ + // Si c'est pas le bon format, on retourne une erreur + if( !preg_match('/^getBy(\w+)$/', $method, $matches) ) return false; + + /* [2] On vérifie que la valeur après 'get' est dans $table_columns + =========================================================*/ + $columnName = strtolower($matches[1]); + + $getAll = $columnName == 'all'; // Si 'getAll' + $getSomething = count($args) > 0 && in_array($columnName, $table_columns); // Si 'getX', et 'X' dans la liste des colonnes + + // Si ni 'getAll' ni 'getSomething' -> erreur + if( !$getAll && !$getSomething ) return false; + + /* [3] On rédige la requête + =========================================================*/ + $getRequestString = 'SELECT * FROM '.static::table_name(); + // Si c'est 'getSomething', on ajoute une condition + if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; + + $getRequest = Database::getPDO()->prepare($getRequestString); + + /* [4] On exécute la requête + =========================================================*/ + // Si 'getSomething', on ajoute le champ + $getRequest->execute(array( + ':value' => $getSomething ? $args[0] : null + )); + + /* [5] On récupère le résultat + =========================================================*/ + return Database::delNumeric( $getRequest->fetchAll() ); + } + + } + + +?> diff --git a/manager/repo/subject.php b/manager/repo/subject.php index 0b364f9..1802e5d 100644 --- a/manager/repo/subject.php +++ b/manager/repo/subject.php @@ -4,7 +4,9 @@ use \manager\Database; use \manager\sessionManager; - class subject{ + class subject extends parentRepo{ + + protected static function table_name(){ static $table_name = 'Personnes'; return $table_name; } diff --git a/manager/repo/token.php b/manager/repo/token.php index d622b37..8222446 100644 --- a/manager/repo/token.php +++ b/manager/repo/token.php @@ -4,8 +4,10 @@ use \manager\sessionManager; use \manager\Database; - class token{ - + class token extends parentRepo{ + + protected static $table_name = 'api_token'; + /* Gestion de la table Token (pour secu) et des derivations * * 1. Gestion des access @@ -37,7 +39,7 @@ FROM api_token ORDER BY expires DESC"); - + /* [3] On retourne les donnees =========================================================*/ return Database::delNumeric( $request->fetchAll() ); @@ -121,7 +123,7 @@ =========================================================*/ if( !Database::check('varchar(3, 50)', $name) || !Database::check('id', $duration) ) return false; - + // On definit la date d'expiration du token $expiration = date('Y-m-d', time()+$duration*3600*24); @@ -209,4 +211,4 @@ } -?> \ No newline at end of file +?> diff --git a/manager/repo/user.php b/manager/repo/user.php index 681a7ca..4c8c21a 100755 --- a/manager/repo/user.php +++ b/manager/repo/user.php @@ -3,61 +3,12 @@ namespace manager\repo; use \manager\Database; use \manager\sessionManager; + use \manager\repo\parentRepo; - class user{ + class user extends parentRepo{ - private static $table_name = 'users'; - private static $columns = null; + protected static function table_name(){ static $table_name = 'users'; return $table_name; } - // Getters dynamiques - public static function __callStatic($method, $args){ - /* [0] Si les colonnes valides ne sont pas chargées, on les charges - =========================================================*/ - if( is_null(self::$columns) ){ - $getColumns = Database::getPDO()->query('SHOW COLUMNS FROM '.self::$table_name); - $cols = $getColumns->fetchAll(); - - self::$columns = array(); - - // On ajoute la liste des colonnes - foreach($cols as $column) - array_push(self::$columns, $column['Field']); - } - - /* [1] On vérifie que la méthode est 'getX', avec X une chaine - =========================================================*/ - // Si c'est pas le bon format, on retourne une erreur - if( !preg_match('/^getBy(\w+)$/', $method, $matches) ) return false; - - /* [2] On vérifie que la valeur après 'get' est dans self::$columns - =========================================================*/ - $columnName = strtolower($matches[1]); - - $getAll = $columnName == 'all'; // Si 'getAll' - $getSomething = count($args) > 0 && in_array($columnName, self::$columns); // Si 'getX', et 'X' dans la liste des colonnes - - // Si ni 'getAll' ni 'getSomething' -> erreur - if( !$getAll && !$getSomething ) return false; - - /* [3] On rédige la requête - =========================================================*/ - $getRequestString = 'SELECT * FROM '.self::$table_name; - // Si c'est 'getSomething', on ajoute une condition - if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; - - $getRequest = Database::getPDO()->prepare($getRequestString); - - /* [4] On exécute la requête - =========================================================*/ - // Si 'getSomething', on ajoute le champ - $getRequest->execute(array( - ':value' => $getSomething ? $args[0] : null - )); - - /* [5] On récupère le résultat - =========================================================*/ - return Database::delNumeric( $getRequest->fetchAll() ); - } /* VERIFICATION DU LOGIN/PASSWORD D'UN UTILISATEUR From 2cad3ac40e4d54f96e9341ae99948480668f8194 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 19 Apr 2016 14:01:34 +0200 Subject: [PATCH 11/21] FIX: Correction pour laisser passer 'getAll' et 'getByXXX' dans parentRepo --- automate.php | 5 +-- manager/module/user.php | 35 --------------------- manager/repo/parentRepo.php | 28 ++++++++++------- manager/repo/user.php | 63 ------------------------------------- 4 files changed, 19 insertions(+), 112 deletions(-) diff --git a/automate.php b/automate.php index a46fcb2..a7601d1 100755 --- a/automate.php +++ b/automate.php @@ -64,7 +64,8 @@ // var_dump($response); - var_dump( \manager\repo\user::getByMail('B@gmail.com') ); - var_dump( \manager\repo\subject::getByPseudo('jeannot') ); + var_dump( \manager\repo\user::getByLogin('xdrm') ); + // var_dump( \manager\repo\user::getByLogin('xdrm') ); + // var_dump( \manager\repo\subject::getByPseudo('jeannot') ); ?> diff --git a/manager/module/user.php b/manager/module/user.php index d6c04cd..68df0c9 100755 --- a/manager/module/user.php +++ b/manager/module/user.php @@ -58,41 +58,6 @@ - - /* RETOURNE L'UTILISATEUR D'ID DONNE - * - * @id_user UID de l'utilisateur en question - * - * @return user Tableau contenant les informations de l'utilisateur - * - */ - public static function getById($params){ - extract($params); - - /* [1] On recupere les donnees de l'utilisateur - =========================================================*/ - $getUser = new Repo('user/getById', array($id_user)); - $user_data = $getUser->answer(); - - // Si aucun utilisateur n'est trouve - if( $user_data === false ) return array('ModuleError' => ManagerError::ModuleError); - - - /* [2] On met les permissions au bon format (string -> array) - =========================================================*/ - $user_data['permission'] = explode( ',', str_replace(' ', '', $user_data['permission']) ); - - /* [3] Gestion du retour - =========================================================*/ - return array( - 'ModuleError' => ManagerError::Success, - 'user' => $user_data - ); - } - - - - /* RETOURNE LA LISTE DE TOUS LES UTILISATEURS * * @return users Tableau contenant les informations de tous les utilisateurs diff --git a/manager/repo/parentRepo.php b/manager/repo/parentRepo.php index 067c909..752235f 100644 --- a/manager/repo/parentRepo.php +++ b/manager/repo/parentRepo.php @@ -23,7 +23,12 @@ // Si static::table_name() NULL if( is_null(static::table_name()) ) return false; - /* [0] On charge la liste des colonnes de la table + /* [1] On vérifie que la méthode est 'getX', avec X une chaine + =========================================================*/ + // Si c'est pas le bon format, on retourne une erreur + if( !preg_match('/^get(?:By(\w+)|(All))$/', $method, $matches) ) return false; + + /* [2] On charge la liste des colonnes de la table =========================================================*/ $getColumns = Database::getPDO()->query('SHOW COLUMNS FROM '.static::table_name()); $cols = $getColumns->fetchAll(); @@ -34,38 +39,37 @@ foreach($cols as $column) array_push($table_columns, $column['Field']); - - /* [1] On vérifie que la méthode est 'getX', avec X une chaine - =========================================================*/ - // Si c'est pas le bon format, on retourne une erreur - if( !preg_match('/^getBy(\w+)$/', $method, $matches) ) return false; - - /* [2] On vérifie que la valeur après 'get' est dans $table_columns + /* [3] On vérifie que la valeur après 'get' est dans $table_columns =========================================================*/ $columnName = strtolower($matches[1]); - $getAll = $columnName == 'all'; // Si 'getAll' + $getAll = count($matches) > 2; // Si 'getAll' $getSomething = count($args) > 0 && in_array($columnName, $table_columns); // Si 'getX', et 'X' dans la liste des colonnes // Si ni 'getAll' ni 'getSomething' -> erreur if( !$getAll && !$getSomething ) return false; - /* [3] On rédige la requête + /* [4] On rédige la requête =========================================================*/ $getRequestString = 'SELECT * FROM '.static::table_name(); + // Si c'est 'getSomething', on ajoute une condition if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; + $getRequestString .= ' ORDER BY 1 ASC'; + + // On prépare la requête $getRequest = Database::getPDO()->prepare($getRequestString); - /* [4] On exécute la requête + /* [5] On exécute la requête =========================================================*/ // Si 'getSomething', on ajoute le champ $getRequest->execute(array( ':value' => $getSomething ? $args[0] : null )); - /* [5] On récupère le résultat + + /* [6] On récupère le résultat =========================================================*/ return Database::delNumeric( $getRequest->fetchAll() ); } diff --git a/manager/repo/user.php b/manager/repo/user.php index 4c8c21a..356e99c 100755 --- a/manager/repo/user.php +++ b/manager/repo/user.php @@ -55,69 +55,6 @@ - /* RETOURNE LES DONNEES D'UN UTILISATEUR D'ID DONNE - * - * @id_user UID de l'utilisateur en question - * - * @return user Tableau contenant les donnees de l'utilisateur s'il existe sinon retourne FALSE - * - */ - public static function getById($id_user){ - /* [0] On formatte et vérifie les INPUT - =========================================================*/ - if( !Database::check('id', $id_user) ) return false; - - /* [1] On effectue la requete - =========================================================*/ - $getUser = Database::getPDO()->prepare("SELECT id_user, login, mail, permission - FROM users - WHERE id_user = :id_user"); - $getUser->execute(array( ':id_user' => $id_user )); - - - /* [2] On recupere le resultat de la requete - =========================================================*/ - $userData = $getUser->fetch(); - - // Si l'utilisateur n'existe pas, on retourne FALSE - if( $userData === false ) return false; - - /* [3] Gestion du retour - =========================================================*/ - return Database::delNumeric( $userData, true ); - } - - - - - - /* RETOURNE LES DONNEES DE TOUS LES UTILISATEURS - * - * @return users Tableau contenant les donnees des utilisateurs, retourne FALSE si erreur - * - */ - public static function getAll(){ - /* [1] On effectue la requete - =========================================================*/ - $getUsers = Database::getPDO()->query("SELECT id_user, login, mail, permission - FROM users - ORDER BY login ASC"); - - - /* [2] On recupere le resultat de la requete - =========================================================*/ - $usersData = $getUsers->fetchAll(); - - // Si l'utilisateur n'existe pas, on retourne FALSE - if( $usersData === false ) return false; - - /* [3] Gestion du retour - =========================================================*/ - return Database::delNumeric( $usersData ); - } - - - /* CREE UN UTILISATEUR * From 1b4b11422507e6e7376041eda52c5052ae01906e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 19 Apr 2016 14:35:40 +0200 Subject: [PATCH 12/21] =?UTF-8?q?Ajout=20de=20'getById'=20utilisant=20la?= =?UTF-8?q?=20cl=C3=A9=20primaire=20pour=20'parentRepo'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gestion d'une clé primaire, une seule pour l'instant --- automate.php | 10 ++++-- config/modules.json | 7 ++-- js/lib/api.js | 2 +- manager/module/user.php | 35 ++++++++++++++++++++ manager/repo/parentRepo.php | 24 ++++++++++---- manager/repo/subject.php | 16 ++++----- manager/repo/token.php | 26 --------------- phpunit/coverage/Database.php.html | 2 +- phpunit/coverage/ManagerError.php.html | 2 +- phpunit/coverage/ResourceDispatcher.php.html | 2 +- phpunit/coverage/autoloader.php.html | 2 +- phpunit/coverage/index.html | 28 ++++++++-------- phpunit/coverage/sessionManager.php.html | 2 +- view/settings.php | 10 +++--- 14 files changed, 96 insertions(+), 72 deletions(-) diff --git a/automate.php b/automate.php index a7601d1..bfb188f 100755 --- a/automate.php +++ b/automate.php @@ -63,9 +63,13 @@ // var_dump($response); + // var_dump( Database::delNumeric( Database::getPDO()->query("SHOW COLUMNS FROM users")->fetchAll() ) ); - var_dump( \manager\repo\user::getByLogin('xdrm') ); - // var_dump( \manager\repo\user::getByLogin('xdrm') ); - // var_dump( \manager\repo\subject::getByPseudo('jeannot') ); + $req_users = new ModuleRequest('user/getAll'); + $answer_users = $req_users->dispatch(); + var_dump($answer_users->get('users')); + // var_dump( \manager\repo\user::getById(1) ); + // // var_dump( \manager\repo\user::getByLogin('xdrm') ); + // // var_dump( \manager\repo\subject::getById(1) ); ?> diff --git a/config/modules.json b/config/modules.json index c57a69d..3562f0c 100755 --- a/config/modules.json +++ b/config/modules.json @@ -87,7 +87,6 @@ } }, - "call_log": { "unserialize": { "description": "Recupere le contenu d'un fichier XML de journal d'appel.", @@ -129,11 +128,11 @@ "generate": { - "description": "Creation d'un token de nom et de duree donnee", + "description": "Création d'un token de nom et de durée donnée", "permissions": ["admin"], "parameters": { - "name": { "description": "Nom attribue au token", "type": "varchar(3,50)" }, - "duration": { "description": "Duree du token en nombre de jours", "type": "numeric" } + "name": { "description": "Nom attribué au token", "type": "varchar(3,50)" }, + "duration": { "description": "Durée du token en nombre de jours", "type": "id" } } } }, diff --git a/js/lib/api.js b/js/lib/api.js index d0fa097..d476a3e 100755 --- a/js/lib/api.js +++ b/js/lib/api.js @@ -56,7 +56,7 @@ APIClass.prototype = { /* DEBUG : affiche la réponse BRUTE de http://host/api/ */ // console.log('http://host/api/ => '+ptrAPI.xhr[i].responseText); - // console.log( JSON.parse(ptrAPI.xhr[i].responseText) ); + console.log( JSON.parse(ptrAPI.xhr[i].responseText) ); /* si success de requête */ if( [0,200].indexOf(ptrAPI.xhr[i].status) > -1 ){ // si fichier existe et reçu diff --git a/manager/module/user.php b/manager/module/user.php index 68df0c9..d6c04cd 100755 --- a/manager/module/user.php +++ b/manager/module/user.php @@ -58,6 +58,41 @@ + + /* RETOURNE L'UTILISATEUR D'ID DONNE + * + * @id_user UID de l'utilisateur en question + * + * @return user Tableau contenant les informations de l'utilisateur + * + */ + public static function getById($params){ + extract($params); + + /* [1] On recupere les donnees de l'utilisateur + =========================================================*/ + $getUser = new Repo('user/getById', array($id_user)); + $user_data = $getUser->answer(); + + // Si aucun utilisateur n'est trouve + if( $user_data === false ) return array('ModuleError' => ManagerError::ModuleError); + + + /* [2] On met les permissions au bon format (string -> array) + =========================================================*/ + $user_data['permission'] = explode( ',', str_replace(' ', '', $user_data['permission']) ); + + /* [3] Gestion du retour + =========================================================*/ + return array( + 'ModuleError' => ManagerError::Success, + 'user' => $user_data + ); + } + + + + /* RETOURNE LA LISTE DE TOUS LES UTILISATEURS * * @return users Tableau contenant les informations de tous les utilisateurs diff --git a/manager/repo/parentRepo.php b/manager/repo/parentRepo.php index 752235f..d1a9c84 100644 --- a/manager/repo/parentRepo.php +++ b/manager/repo/parentRepo.php @@ -31,30 +31,42 @@ /* [2] On charge la liste des colonnes de la table =========================================================*/ $getColumns = Database::getPDO()->query('SHOW COLUMNS FROM '.static::table_name()); - $cols = $getColumns->fetchAll(); + $cols = Database::delNumeric( $getColumns->fetchAll() ); - $table_columns = array(); + $table_columns = array( + '_PRIMARY_' => array() // Contiendra les champs de la clé primaire + ); // On ajoute la liste des colonnes - foreach($cols as $column) + foreach($cols as $column){ + // On enregistre la clé primaire (si elle l'est) + if( $column['Key'] == 'PRI' ) array_push($table_columns['_PRIMARY_'], $column['Field']); + array_push($table_columns, $column['Field']); + } /* [3] On vérifie que la valeur après 'get' est dans $table_columns =========================================================*/ $columnName = strtolower($matches[1]); $getAll = count($matches) > 2; // Si 'getAll' + $getById = $columnName == 'id'; $getSomething = count($args) > 0 && in_array($columnName, $table_columns); // Si 'getX', et 'X' dans la liste des colonnes // Si ni 'getAll' ni 'getSomething' -> erreur - if( !$getAll && !$getSomething ) return false; + if( !$getById && !$getAll && !$getSomething ) return false; /* [4] On rédige la requête =========================================================*/ $getRequestString = 'SELECT * FROM '.static::table_name(); + // Si c'est 'getById', on ajoute une condition + if( $getById ){ + $getRequestString .= ' WHERE '.$table_columns['_PRIMARY_'][0].' = :value'; + // Si c'est 'getSomething', on ajoute une condition - if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; + }else if( $getSomething ) + $getRequestString .= ' WHERE '.$columnName.' = :value'; $getRequestString .= ' ORDER BY 1 ASC'; @@ -65,7 +77,7 @@ =========================================================*/ // Si 'getSomething', on ajoute le champ $getRequest->execute(array( - ':value' => $getSomething ? $args[0] : null + ':value' => ($getSomething||$getById) ? $args[0] : null )); diff --git a/manager/repo/subject.php b/manager/repo/subject.php index 1802e5d..de23214 100644 --- a/manager/repo/subject.php +++ b/manager/repo/subject.php @@ -6,7 +6,7 @@ class subject extends parentRepo{ - protected static function table_name(){ static $table_name = 'Personnes'; return $table_name; } + protected static function table_name(){ static $table_name = 'sujets'; return $table_name; } @@ -21,9 +21,9 @@ public static function getById($id_subject){ /* [1] On effectue la requete =========================================================*/ - $getSubject = Database::getPDO()->prepare("SELECT idPersonne, pseudo, prenom, nom, id_facebook, telephone - FROM Personnes - WHERE idPersonne = :id_subject"); + $getSubject = Database::getPDO()->prepare("SELECT idSujet, pseudo, prenom, nom, id_facebook, telephone + FROM sujets + WHERE idSujet = :id_subject"); $getSubject->execute(array( ':id_subject' => $id_subject )); @@ -51,9 +51,9 @@ public static function getAll(){ /* [1] On effectue la requete =========================================================*/ - $getSubjects = Database::getPDO()->query("SELECT idPersonne, pseudo, prenom, nom, id_facebook, telephone - FROM Personnes - ORDER BY idPersonne ASC"); + $getSubjects = Database::getPDO()->query("SELECT idSujet, pseudo, prenom, nom, id_facebook, telephone + FROM sujets + ORDER BY idSujet ASC"); /* [2] On recupere le resultat de la requete @@ -97,7 +97,7 @@ /* [1] On écrit la requête =========================================================*/ - $request_create = 'INSERT INTO Personnes(idPersonne, pseudo, nom, prenom, id_facebook, telephone) '; + $request_create = 'INSERT INTO sujets(idSujet, pseudo, nom, prenom, id_facebook, telephone) '; $request_create .= 'VALUES ('; $request_create .= 'DEFAULT, '; // idPersone $request_create .= strlen($username) ? ':pseudo, ' : 'NULL, '; // pseudo diff --git a/manager/repo/token.php b/manager/repo/token.php index 8222446..83eaa00 100644 --- a/manager/repo/token.php +++ b/manager/repo/token.php @@ -47,32 +47,6 @@ - /* RETOURNE LE TOKEN D'ID SPECIFIE OU FALSE - * - * @id_token UID du token en question - * - * @return token Retourne les donnees du token ou FALSE si erreur - * - */ - public static function getById($id_token){ - /* [0] Verification des INPUT - =========================================================*/ - if( !Database::check('id', $id_token) ) return false; - - - /* [1] On cherche dans la bdd - =========================================================*/ - $get_token = Database::getPDO()->prepare("SELECT id_token FROM api_token WHERE id_token = :id_token"); - $get_token->execute( array( ':id_token' => $id_token ) ); - - - /* [2] On renvoie la valeur ou FALSE - =========================================================*/ - return $get_token->fetch(); - } - - - /* VERIFIE SI UN TOKEN EST VALIDE * * @token Token en question diff --git a/phpunit/coverage/Database.php.html b/phpunit/coverage/Database.php.html index 8f67e86..0fb6780 100755 --- a/phpunit/coverage/Database.php.html +++ b/phpunit/coverage/Database.php.html @@ -612,7 +612,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/phpunit/coverage/ManagerError.php.html b/phpunit/coverage/ManagerError.php.html index 6051d52..94ce055 100755 --- a/phpunit/coverage/ManagerError.php.html +++ b/phpunit/coverage/ManagerError.php.html @@ -247,7 +247,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/phpunit/coverage/ResourceDispatcher.php.html b/phpunit/coverage/ResourceDispatcher.php.html index 9bb2f42..83ef269 100755 --- a/phpunit/coverage/ResourceDispatcher.php.html +++ b/phpunit/coverage/ResourceDispatcher.php.html @@ -517,7 +517,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/phpunit/coverage/autoloader.php.html b/phpunit/coverage/autoloader.php.html index eb4efed..c66182a 100755 --- a/phpunit/coverage/autoloader.php.html +++ b/phpunit/coverage/autoloader.php.html @@ -214,7 +214,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/phpunit/coverage/index.html b/phpunit/coverage/index.html index fc1de51..a02d7ad 100755 --- a/phpunit/coverage/index.html +++ b/phpunit/coverage/index.html @@ -43,13 +43,13 @@ Total
-
- 66.83% covered (warning) +
+ 63.38% covered (warning)
-
66.83%
-
270 / 404
+
63.38%
+
270 / 426
44.44% covered (danger) @@ -59,13 +59,13 @@
44.44%
20 / 45
-
- 11.11% covered (danger) +
+ 10.00% covered (danger)
-
11.11%
-
1 / 9
+
10.00%
+
1 / 10
@@ -99,13 +99,13 @@ repo
-
- 16.28% covered (danger) +
+ 10.77% covered (danger)
-
16.28%
-
7 / 43
+
10.77%
+
7 / 65
20.00% covered (danger) @@ -121,7 +121,7 @@
0.00%
-
0 / 1
+
0 / 2
@@ -350,7 +350,7 @@ High: 90% to 100%

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/phpunit/coverage/sessionManager.php.html b/phpunit/coverage/sessionManager.php.html index f0d06d6..8f1a8bc 100755 --- a/phpunit/coverage/sessionManager.php.html +++ b/phpunit/coverage/sessionManager.php.html @@ -315,7 +315,7 @@ Dead Code

- Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Mon Apr 18 20:36:30 UTC 2016. + Generated by PHP_CodeCoverage 2.1.7 using PHP 5.6.11-1ubuntu3.1 and PHPUnit 4.7.6 at Tue Apr 19 12:25:45 UTC 2016.

diff --git a/view/settings.php b/view/settings.php index f22dc5f..59f183c 100755 --- a/view/settings.php +++ b/view/settings.php @@ -27,7 +27,7 @@ if( permission('admin') ){ ?>
Gestion des accès distants

- +
@@ -39,7 +39,7 @@ if( permission('admin') ){
Liste des accès distants actifs. Ils seront automatiquement désactivés a la date d'expiration. Veuillez toutefois les supprimer.
-
+
Nom de l'accès
Duree de vie (jours)
@@ -83,7 +83,7 @@ if( permission('admin') ){ =========================================================*/ // permission: admin //=======================================================// - + /* (1) On recupere la liste des utilisateurs */ $req_users = new ModuleRequest('user/getAll'); $answer_users = $req_users->dispatch(); @@ -96,7 +96,7 @@ if( permission('admin') ){ ?>
Gestion des utilisateurs

- +
@@ -156,4 +156,4 @@ if( permission('admin') ){ - \ No newline at end of file + From 8e58358314369335aed15223337c32e8a6ff7387 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Tue, 19 Apr 2016 15:30:33 +0200 Subject: [PATCH 13/21] Correction de user & token (modules+repos) --- automate.php | 8 +- css/reset.scss | 4 +- js/lib/api.js | 8 +- .../highcharts/js/modules/canvas-tools.src.js | 946 ++-- js/lib/highcharts/js/modules/heatmap.src.js | 2 +- js/lib/page-manager.js | 2 +- manager/module/token.php | 11 +- manager/module/user.php | 10 +- manager/repo/parentRepo.php | 3 +- manager/repo/token.php | 10 +- tags | 4373 ----------------- view/settings.php | 2 +- 12 files changed, 505 insertions(+), 4874 deletions(-) delete mode 100644 tags diff --git a/automate.php b/automate.php index bfb188f..de6791a 100755 --- a/automate.php +++ b/automate.php @@ -65,9 +65,11 @@ // var_dump( Database::delNumeric( Database::getPDO()->query("SHOW COLUMNS FROM users")->fetchAll() ) ); - $req_users = new ModuleRequest('user/getAll'); - $answer_users = $req_users->dispatch(); - var_dump($answer_users->get('users')); + $create_token = new Repo('token/generate', array( + 'name' => 'test2', + 'duration' => 10 + )); + var_dump( $create_token->answer() ); // var_dump( \manager\repo\user::getById(1) ); // // var_dump( \manager\repo\user::getByLogin('xdrm') ); // // var_dump( \manager\repo\subject::getById(1) ); diff --git a/css/reset.scss b/css/reset.scss index 6675ec8..eebc0aa 100755 --- a/css/reset.scss +++ b/css/reset.scss @@ -409,7 +409,7 @@ textarea { /** * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + * the default cannot safely be changed in Chrome and Safari on OS X. */ optgroup { @@ -431,4 +431,4 @@ table { td, th { padding: 0; -} \ No newline at end of file +} diff --git a/js/lib/api.js b/js/lib/api.js index d476a3e..4930061 100755 --- a/js/lib/api.js +++ b/js/lib/api.js @@ -1,5 +1,5 @@ /* classe API */ -function APIClass(target){ this.target = target; }; +function APIClass(target){ this.target = target; } APIClass.prototype = { xhr: [], // tableau d'objets pour les requêtes ajax @@ -55,8 +55,8 @@ APIClass.prototype = { if( ptrAPI.xhr[i].readyState == 4 ){ // si la requête est terminée /* DEBUG : affiche la réponse BRUTE de http://host/api/ */ - // console.log('http://host/api/ => '+ptrAPI.xhr[i].responseText); - console.log( JSON.parse(ptrAPI.xhr[i].responseText) ); + console.log('http://host/api/ => '+ptrAPI.xhr[i].responseText); + // console.log( JSON.parse(ptrAPI.xhr[i].responseText) ); /* si success de requête */ if( [0,200].indexOf(ptrAPI.xhr[i].status) > -1 ){ // si fichier existe et reçu @@ -68,7 +68,7 @@ APIClass.prototype = { pHandler({ModuleError:3}); } - } + }; // on créé un formulaire POST (virtuel) var form = new FormData(); diff --git a/js/lib/highcharts/js/modules/canvas-tools.src.js b/js/lib/highcharts/js/modules/canvas-tools.src.js index 0a839e3..9c4eb3b 100755 --- a/js/lib/highcharts/js/modules/canvas-tools.src.js +++ b/js/lib/highcharts/js/modules/canvas-tools.src.js @@ -289,7 +289,7 @@ function RGBColor(color_string) /** * @license canvg.js - Javascript SVG parser and renderer on Canvas - * MIT Licensed + * MIT Licensed * Gabe Lerner (gabelerner@gmail.com) * http://code.google.com/p/canvg/ * @@ -345,13 +345,13 @@ if(!Array.prototype.indexOf){ canvg(c, div.innerHTML); } return; - } + } opts = opts || {}; - + if (typeof target == 'string') { target = document.getElementById(target); } - + // reuse class per canvas var svg; if (target.svg == null) { @@ -363,7 +363,7 @@ if(!Array.prototype.indexOf){ svg.stop(); } svg.opts = opts; - + var ctx = target.getContext('2d'); if (typeof(s.documentElement) != 'undefined') { // load from xml doc @@ -381,10 +381,10 @@ if(!Array.prototype.indexOf){ function build() { var svg = { }; - + svg.FRAMERATE = 30; svg.MAX_VIRTUAL_PIXELS = 30000; - + // globals svg.init = function(ctx) { svg.Definitions = {}; @@ -404,14 +404,14 @@ if(!Array.prototype.indexOf){ if (d != null && typeof(d) == 'number') return d; if (d == 'x') return this.width(); if (d == 'y') return this.height(); - return Math.sqrt(Math.pow(this.width(), 2) + Math.pow(this.height(), 2)) / Math.sqrt(2); + return Math.sqrt(Math.pow(this.width(), 2) + Math.pow(this.height(), 2)) / Math.sqrt(2); } }); } svg.init(); - + // images loaded - svg.ImagesLoaded = function() { + svg.ImagesLoaded = function() { for (var i=0; i]*>/, ''); var xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); xmlDoc.async = 'false'; - xmlDoc.loadXML(xml); + xmlDoc.loadXML(xml); return xmlDoc; - } + } } - + svg.Property = function(name, value) { this.name = name; this.value = value; - + this.hasValue = function() { return (this.value != null && this.value !== ''); } - + // return the numerical value of the property this.numValue = function() { if (!this.hasValue()) return 0; - + var n = parseFloat(this.value); if ((this.value + '').match(/%$/)) { n = n / 100.0; } return n; } - + this.valueOrDefault = function(def) { if (this.hasValue()) return this.value; return def; } - + this.numValueOrDefault = function(def) { if (this.hasValue()) return this.numValue(); return def; } - + /* EXTENSIONS */ var that = this; - + // color extensions this.Color = { // augment the current color value with the opacity @@ -500,7 +500,7 @@ if(!Array.prototype.indexOf){ return new svg.Property(that.name, newValue); } } - + // definition extensions this.Definition = { // get the definition from the definitions table @@ -508,43 +508,43 @@ if(!Array.prototype.indexOf){ var name = that.value.replace(/^(url\()?#([^\)]+)\)?$/, '$2'); return svg.Definitions[name]; }, - + isUrl: function() { return that.value.indexOf('url(') == 0 }, - + getFillStyle: function(e) { var def = this.getDefinition(); - + // gradient if (def != null && def.createGradient) { return def.createGradient(svg.ctx, e); } - + // pattern if (def != null && def.createPattern) { return def.createPattern(svg.ctx, e); } - + return null; } } - + // length extensions this.Length = { DPI: function(viewPort) { return 96.0; // TODO: compute? }, - + EM: function(viewPort) { var em = 12; - + var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize); if (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort); - + return em; }, - + // get the length as pixels toPixels: function(viewPort) { if (!that.hasValue()) return 0; @@ -561,7 +561,7 @@ if(!Array.prototype.indexOf){ return that.numValue(); } } - + // time extensions this.Time = { // get the time as milliseconds @@ -573,7 +573,7 @@ if(!Array.prototype.indexOf){ return that.numValue(); } } - + // angle extensions this.Angle = { // get the angle as radians @@ -587,25 +587,25 @@ if(!Array.prototype.indexOf){ } } } - + // fonts svg.Font = new (function() { this.Styles = ['normal','italic','oblique','inherit']; this.Variants = ['normal','small-caps','inherit']; this.Weights = ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900','inherit']; - - this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { + + this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font); - return { - fontFamily: fontFamily || f.fontFamily, - fontSize: fontSize || f.fontSize, - fontStyle: fontStyle || f.fontStyle, - fontWeight: fontWeight || f.fontWeight, + return { + fontFamily: fontFamily || f.fontFamily, + fontSize: fontSize || f.fontSize, + fontStyle: fontStyle || f.fontStyle, + fontWeight: fontWeight || f.fontWeight, fontVariant: fontVariant || f.fontVariant, - toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } - } + toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } + } } - + var that = this; this.Parse = function(s) { var f = {}; @@ -622,7 +622,7 @@ if(!Array.prototype.indexOf){ return f; } }); - + // points and paths svg.ToNumberArray = function(s) { var a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' '); @@ -630,15 +630,15 @@ if(!Array.prototype.indexOf){ a[i] = parseFloat(a[i]); } return a; - } + } svg.Point = function(x, y) { this.x = x; this.y = y; - + this.angleTo = function(p) { return Math.atan2(p.y - this.y, p.x - this.x); } - + this.applyTransform = function(v) { var xp = this.x * v[0] + this.y * v[2] + v[4]; var yp = this.x * v[1] + this.y * v[3] + v[5]; @@ -658,20 +658,20 @@ if(!Array.prototype.indexOf){ } return path; } - + // bounding box svg.BoundingBox = function(x1, y1, x2, y2) { // pass in initial points if you want this.x1 = Number.NaN; this.y1 = Number.NaN; this.x2 = Number.NaN; this.y2 = Number.NaN; - + this.x = function() { return this.x1; } this.y = function() { return this.y1; } this.width = function() { return this.x2 - this.x1; } this.height = function() { return this.y2 - this.y1; } - - this.addPoint = function(x, y) { + + this.addPoint = function(x, y) { if (x != null) { if (isNaN(this.x1) || isNaN(this.x2)) { this.x1 = x; @@ -680,7 +680,7 @@ if(!Array.prototype.indexOf){ if (x < this.x1) this.x1 = x; if (x > this.x2) this.x2 = x; } - + if (y != null) { if (isNaN(this.y1) || isNaN(this.y2)) { this.y1 = y; @@ -689,15 +689,15 @@ if(!Array.prototype.indexOf){ if (y < this.y1) this.y1 = y; if (y > this.y2) this.y2 = y; } - } + } this.addX = function(x) { this.addPoint(x, null); } this.addY = function(y) { this.addPoint(null, y); } - + this.addBoundingBox = function(bb) { this.addPoint(bb.x1, bb.y1); this.addPoint(bb.x2, bb.y2); } - + this.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) { var cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0) var cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0) @@ -705,25 +705,25 @@ if(!Array.prototype.indexOf){ var cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0) this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y, cp2y, p2x, p2y); } - + this.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) { // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html var p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y]; this.addPoint(p0[0], p0[1]); this.addPoint(p3[0], p3[1]); - + for (i=0; i<=1; i++) { - var f = function(t) { + var f = function(t) { return Math.pow(1-t, 3) * p0[i] + 3 * Math.pow(1-t, 2) * t * p1[i] + 3 * (1-t) * Math.pow(t, 2) * p2[i] + Math.pow(t, 3) * p3[i]; } - + var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i]; var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i]; var c = 3 * p1[i] - 3 * p0[i]; - + if (a == 0) { if (b == 0) continue; var t = -c / b; @@ -733,7 +733,7 @@ if(!Array.prototype.indexOf){ } continue; } - + var b2ac = Math.pow(b, 2) - 4 * c * a; if (b2ac < 0) continue; var t1 = (-b + Math.sqrt(b2ac)) / (2 * a); @@ -748,23 +748,23 @@ if(!Array.prototype.indexOf){ } } } - + this.isPointInBox = function(x, y) { return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2); } - + this.addPoint(x1, y1); this.addPoint(x2, y2); } - + // transforms - svg.Transform = function(v) { + svg.Transform = function(v) { var that = this; this.Type = {} - + // translate this.Type.translate = function(s) { - this.p = svg.CreatePoint(s); + this.p = svg.CreatePoint(s); this.apply = function(ctx) { ctx.translate(this.p.x || 0.0, this.p.y || 0.0); } @@ -772,7 +772,7 @@ if(!Array.prototype.indexOf){ p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); } } - + // rotate this.Type.rotate = function(s) { var a = svg.ToNumberArray(s); @@ -789,9 +789,9 @@ if(!Array.prototype.indexOf){ p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]); p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]); - } + } } - + this.Type.scale = function(s) { this.p = svg.CreatePoint(s); this.apply = function(ctx) { @@ -799,9 +799,9 @@ if(!Array.prototype.indexOf){ } this.applyToPoint = function(p) { p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]); - } + } } - + this.Type.matrix = function(s) { this.m = svg.ToNumberArray(s); this.apply = function(ctx) { @@ -809,44 +809,44 @@ if(!Array.prototype.indexOf){ } this.applyToPoint = function(p) { p.applyTransform(this.m); - } + } } - + this.Type.SkewBase = function(s) { this.base = that.Type.matrix; this.base(s); this.angle = new svg.Property('angle', s); } this.Type.SkewBase.prototype = new this.Type.matrix; - + this.Type.skewX = function(s) { this.base = that.Type.SkewBase; this.base(s); this.m = [1, 0, Math.tan(this.angle.Angle.toRadians()), 1, 0, 0]; } this.Type.skewX.prototype = new this.Type.SkewBase; - + this.Type.skewY = function(s) { this.base = that.Type.SkewBase; this.base(s); this.m = [1, Math.tan(this.angle.Angle.toRadians()), 0, 1, 0, 0]; } this.Type.skewY.prototype = new this.Type.SkewBase; - + this.transforms = []; - + this.apply = function(ctx) { for (var i=0; i= this.tokens.length - 1; } - + this.isCommandOrEnd = function() { if (this.isEnd()) return true; return this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null; } - + this.isRelativeCommand = function() { return this.command == this.command.toLowerCase(); } - + this.getToken = function() { this.i = this.i + 1; return this.tokens[this.i]; } - + this.getScalar = function() { return parseFloat(this.getToken()); } - + this.nextCommand = function() { this.previousCommand = this.command; this.command = this.getToken(); - } - + } + this.getPoint = function() { var p = new svg.Point(this.getScalar(), this.getScalar()); return this.makeAbsolute(p); } - + this.getAsControlPoint = function() { var p = this.getPoint(); this.control = p; return p; } - + this.getAsCurrentPoint = function() { var p = this.getPoint(); this.current = p; - return p; + return p; } - + this.getReflectedControlPoint = function() { if (this.previousCommand.toLowerCase() != 'c' && this.previousCommand.toLowerCase() != 's') { return this.current; } - + // reflect point - var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y); + var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y); return p; } - + this.makeAbsolute = function(p) { if (this.isRelativeCommand()) { p.x = this.current.x + p.x; @@ -1477,7 +1477,7 @@ if(!Array.prototype.indexOf){ } return p; } - + this.addMarker = function(p, from, priorTo) { // if the last angle isn't filled in because we didn't have this point yet ... if (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) { @@ -1485,12 +1485,12 @@ if(!Array.prototype.indexOf){ } this.addMarkerAngle(p, from == null ? null : from.angleTo(p)); } - + this.addMarkerAngle = function(p, a) { this.points.push(p); this.angles.push(a); - } - + } + this.getMarkerPoints = function() { return this.points; } this.getMarkerAngles = function() { for (var i=0; i this.maxDuration) { // loop for indefinitely repeating animations @@ -1953,49 +1953,49 @@ if(!Array.prototype.indexOf){ else { return false; // no updates made } - } + } this.duration = this.duration + delta; - + // if we're past the begin time var updated = false; if (this.begin < this.duration) { var newValue = this.calcValue(); // tween - + if (this.attribute('type').hasValue()) { // for transform, etc. var type = this.attribute('type').value; newValue = type + '(' + newValue + ')'; } - + this.getProperty().value = newValue; updated = true; } - + return updated; } - + // fraction of duration we've covered this.progress = function() { return ((this.duration - this.begin) / (this.maxDuration - this.begin)); - } + } } svg.Element.AnimateBase.prototype = new svg.Element.ElementBase; - + // animate element svg.Element.animate = function(node) { this.base = svg.Element.AnimateBase; this.base(node); - + this.calcValue = function() { var from = this.attribute('from').numValue(); var to = this.attribute('to').numValue(); - + // tween value linearly - return from + (to - from) * this.progress(); + return from + (to - from) * this.progress(); }; } svg.Element.animate.prototype = new svg.Element.AnimateBase; - + // animate color element svg.Element.animateColor = function(node) { this.base = svg.Element.AnimateBase; @@ -2004,7 +2004,7 @@ if(!Array.prototype.indexOf){ this.calcValue = function() { var from = new RGBColor(this.attribute('from').value); var to = new RGBColor(this.attribute('to').value); - + if (from.ok && to.ok) { // tween color linearly var r = from.r + (to.r - from.r) * this.progress(); @@ -2016,26 +2016,26 @@ if(!Array.prototype.indexOf){ }; } svg.Element.animateColor.prototype = new svg.Element.AnimateBase; - + // animate transform element svg.Element.animateTransform = function(node) { this.base = svg.Element.animate; this.base(node); } svg.Element.animateTransform.prototype = new svg.Element.animate; - + // font element svg.Element.font = function(node) { this.base = svg.Element.ElementBase; this.base(node); - this.horizAdvX = this.attribute('horiz-adv-x').numValue(); - + this.horizAdvX = this.attribute('horiz-adv-x').numValue(); + this.isRTL = false; this.isArabic = false; this.fontFace = null; this.missingGlyph = null; - this.glyphs = []; + this.glyphs = []; for (var i=0; i0 && text[i-1]!=' ' && i0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial'; if (typeof(font.glyphs[c]) != 'undefined') { @@ -2184,7 +2184,7 @@ if(!Array.prototype.indexOf){ if (glyph == null) glyph = font.missingGlyph; return glyph; } - + this.renderChildren = function(ctx) { var customFont = this.parent.style('font-family').Definition.getDefinition(); if (customFont != null) { @@ -2192,7 +2192,7 @@ if(!Array.prototype.indexOf){ var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle); var text = this.getText(); if (customFont.isRTL) text = text.split("").reverse().join(""); - + var dx = svg.ToNumberArray(this.parent.attribute('dx').value); for (var i=0; i 0 ? node.childNodes[0].nodeValue : // element node.text; @@ -2267,34 +2267,34 @@ if(!Array.prototype.indexOf){ } } svg.Element.tspan.prototype = new svg.Element.TextElementBase; - + // tref svg.Element.tref = function(node) { this.base = svg.Element.TextElementBase; this.base(node); - + this.getText = function() { var element = this.attribute('xlink:href').Definition.getDefinition(); if (element != null) return element.children[0].getText(); } } - svg.Element.tref.prototype = new svg.Element.TextElementBase; - + svg.Element.tref.prototype = new svg.Element.TextElementBase; + // a element svg.Element.a = function(node) { this.base = svg.Element.TextElementBase; this.base(node); - + this.hasText = true; for (var i=0; i 1 ? node.childNodes[1].nodeValue : ''); css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments @@ -2457,60 +2457,60 @@ if(!Array.prototype.indexOf){ } } svg.Element.style.prototype = new svg.Element.ElementBase; - - // use element + + // use element svg.Element.use = function(node) { this.base = svg.Element.RenderedElementBase; this.base(node); - + this.baseSetContext = this.setContext; this.setContext = function(ctx) { this.baseSetContext(ctx); if (this.attribute('x').hasValue()) ctx.translate(this.attribute('x').Length.toPixels('x'), 0); if (this.attribute('y').hasValue()) ctx.translate(0, this.attribute('y').Length.toPixels('y')); } - + this.getDefinition = function() { var element = this.attribute('xlink:href').Definition.getDefinition(); if (this.attribute('width').hasValue()) element.attribute('width', true).value = this.attribute('width').value; if (this.attribute('height').hasValue()) element.attribute('height', true).value = this.attribute('height').value; return element; } - + this.path = function(ctx) { var element = this.getDefinition(); if (element != null) element.path(ctx); } - + this.renderChildren = function(ctx) { var element = this.getDefinition(); if (element != null) element.render(ctx); } } svg.Element.use.prototype = new svg.Element.RenderedElementBase; - + // mask element svg.Element.mask = function(node) { this.base = svg.Element.ElementBase; this.base(node); - + this.apply = function(ctx, element) { - // render as temp svg + // render as temp svg var x = this.attribute('x').Length.toPixels('x'); var y = this.attribute('y').Length.toPixels('y'); var width = this.attribute('width').Length.toPixels('x'); var height = this.attribute('height').Length.toPixels('y'); - + // temporarily remove mask to avoid recursion var mask = element.attribute('mask').value; element.attribute('mask').value = ''; - + var cMask = document.createElement('canvas'); cMask.width = x + width; cMask.height = y + height; var maskCtx = cMask.getContext('2d'); this.renderChildren(maskCtx); - + var c = document.createElement('canvas'); c.width = x + width; c.height = y + height; @@ -2519,25 +2519,25 @@ if(!Array.prototype.indexOf){ tempCtx.globalCompositeOperation = 'destination-in'; tempCtx.fillStyle = maskCtx.createPattern(cMask, 'no-repeat'); tempCtx.fillRect(0, 0, x + width, y + height); - + ctx.fillStyle = tempCtx.createPattern(c, 'no-repeat'); ctx.fillRect(0, 0, x + width, y + height); - + // reassign mask - element.attribute('mask').value = mask; + element.attribute('mask').value = mask; } - + this.render = function(ctx) { // NO RENDER } } svg.Element.mask.prototype = new svg.Element.ElementBase; - + // clip element svg.Element.clipPath = function(node) { this.base = svg.Element.ElementBase; this.base(node); - + this.apply = function(ctx) { for (var i=0; i UID du token en question + * @token_id UID du token en question * */ public static function remove($params){ @@ -22,9 +22,10 @@ /* [1] Suppression du token =========================================================*/ - $remove = new Repo('token/remove', array($id_token)); + $remove = new Repo('token/remove', array($token_id)); + // On renvoie une erreur si une erreur intervient pendant la suppression - if( !$remove->answer() ) return array('ModuleError' => ManagerError::ModuleError); + if( $remove->answer() === false ) return array('ModuleError' => ManagerError::ModuleError); /* [n] Gestion du retour quand tout est normal @@ -48,10 +49,10 @@ */ public static function generate($params){ extract($params); - + /* [0] Verification des INPUT =========================================================*/ - if( !Database::check('varchar(50)', $name) || !Database::check('numeric', $duration) ) + if( !Database::check('varchar(4,50)', $name) || !Database::check('id', $duration) ) return array('ModuleError' => ManagerError::ParamError); // erreur de parametre diff --git a/manager/module/user.php b/manager/module/user.php index d6c04cd..81c3273 100755 --- a/manager/module/user.php +++ b/manager/module/user.php @@ -75,18 +75,18 @@ $user_data = $getUser->answer(); // Si aucun utilisateur n'est trouve - if( $user_data === false ) return array('ModuleError' => ManagerError::ModuleError); + if( count($user_data) == 0 ) return array('ModuleError' => ManagerError::ModuleError); /* [2] On met les permissions au bon format (string -> array) =========================================================*/ - $user_data['permission'] = explode( ',', str_replace(' ', '', $user_data['permission']) ); + $user_data[0]['permission'] = explode( ',', str_replace(' ', '', $user_data[0]['permission']) ); /* [3] Gestion du retour =========================================================*/ return array( 'ModuleError' => ManagerError::Success, - 'user' => $user_data + 'user' => $user_data[0] ); } @@ -179,7 +179,7 @@ $exists_status = $exists->answer(); // Si l'utilisateur n'existe pas, on retourne une erreur - if( $exists_status === false ) return array( 'ModuleError' => ManagerError::ModuleError ); + if( count($exists_status) == 0 ) return array( 'ModuleError' => ManagerError::ModuleError ); /* [2] Suppression de l'utilisateur =========================================================*/ @@ -193,7 +193,7 @@ $removed_status = $removed->answer(); // Si l'utilisateur n'existe pas, on retourne une erreur - if( $removed_status !== false ) return array( 'ModuleError' => ManagerError::ModuleError ); + if( count($removed_status) > 0 ) return array( 'ModuleError' => ManagerError::ModuleError ); /* [4] Gestion du retour diff --git a/manager/repo/parentRepo.php b/manager/repo/parentRepo.php index d1a9c84..575b4b5 100644 --- a/manager/repo/parentRepo.php +++ b/manager/repo/parentRepo.php @@ -64,6 +64,8 @@ if( $getById ){ $getRequestString .= ' WHERE '.$table_columns['_PRIMARY_'][0].' = :value'; + // TODO: Les autres clés primaires si elle est composée avec les autres arguments + // Si c'est 'getSomething', on ajoute une condition }else if( $getSomething ) $getRequestString .= ' WHERE '.$columnName.' = :value'; @@ -80,7 +82,6 @@ ':value' => ($getSomething||$getById) ? $args[0] : null )); - /* [6] On récupère le résultat =========================================================*/ return Database::delNumeric( $getRequest->fetchAll() ); diff --git a/manager/repo/token.php b/manager/repo/token.php index 83eaa00..d1883c1 100644 --- a/manager/repo/token.php +++ b/manager/repo/token.php @@ -6,7 +6,7 @@ class token extends parentRepo{ - protected static $table_name = 'api_token'; + protected static function table_name(){ static $table_name = 'api_token'; return $table_name; } /* Gestion de la table Token (pour secu) et des derivations * @@ -35,7 +35,7 @@ public static function getAll(){ /* [1] On prepare et execute la requete =========================================================*/ - $request = Database::getPDO()->query("SELECT id_token as id, name, token, expires, (CURDATE() > expires) as expired + $request = Database::getPDO()->query("SELECT id_token, name, token, expires, (CURDATE() > expires) as expired FROM api_token ORDER BY expires DESC"); @@ -95,7 +95,7 @@ public static function generate($name, $duration){ /* [0] Verification des INPUT =========================================================*/ - if( !Database::check('varchar(3, 50)', $name) || !Database::check('id', $duration) ) return false; + if( !Database::check('varchar(3,50)', $name) || !Database::check('id', $duration) ) return false; // On definit la date d'expiration du token @@ -167,7 +167,7 @@ /* [1] On verifie l'existance du token =========================================================*/ - if( !self::getById($id_token) ) return false; + if( count(self::getById($id_token)) == 0 ) return false; /* [2] Suppression du token @@ -179,7 +179,7 @@ /* [3] On retourne VRAI si le token est bien supprime =========================================================*/ - return self::getById($id_token) === false; + return count(self::getById($id_token)) == 0; } } diff --git a/tags b/tags deleted file mode 100644 index e4157c5..0000000 --- a/tags +++ /dev/null @@ -1,4373 +0,0 @@ -!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ -!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ -!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ -!_TAG_PROGRAM_NAME Exuberant Ctags // -!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ -!_TAG_PROGRAM_VERSION 5.9~svn20110310 // -$ js/lib/reset.js /^function $(idOrClass){$/;" f -$.$.$.$ phpunit/coverage/js/bootstrap.min.js /^if(typeof jQuery==="undefined"){throw new Error("Bootstrap's JavaScript requires jQuery")}+function($){"use strict";var version=$.fn.jquery.split(" ")[0].split(".");if(version[0]<2&&version[1]<9||version[0]==1&&version[1]==9&&version[2]<1){throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}}(jQuery);+function($){"use strict";function transitionEnd(){var el=document.createElement("bootstrap");var transEndEventNames={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var name in transEndEventNames){if(el.style[name]!==undefined){return{end:transEndEventNames[name]}}}return false}$.fn.emulateTransitionEnd=function(duration){var called=false;var $el=this;$(this).one("bsTransitionEnd",function(){called=true});var callback=function(){if(!called)$($el).trigger($.support.transition.end)};setTimeout(callback,duration);return this};$(function(){$.support.transition=transitionEnd();if(!$.support.transition)return;$.event.special.bsTransitionEnd={bindType:$.support.transition.end,delegateType:$.support.transition.end,handle:function(e){if($(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}}})}(jQuery);+function($){"use strict";var dismiss='[data-dismiss="alert"]';var Alert=function(el){$(el).on("click",dismiss,this.close)};Alert.VERSION="3.3.5";Alert.TRANSITION_DURATION=150;Alert.prototype.close=function(e){var $this=$(this);var selector=$this.attr("data-target");if(!selector){selector=$this.attr("href");selector=selector&&selector.replace(\/.*(?=#[^\\s]*$)\/,"")}var $parent=$(selector);if(e)e.preventDefault();if(!$parent.length){$parent=$this.closest(".alert")}$parent.trigger(e=$.Event("close.bs.alert"));if(e.isDefaultPrevented())return;$parent.removeClass("in");function removeElement(){$parent.detach().trigger("closed.bs.alert").remove()}$.support.transition&&$parent.hasClass("fade")?$parent.one("bsTransitionEnd",removeElement).emulateTransitionEnd(Alert.TRANSITION_DURATION):removeElement()};function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.alert");if(!data)$this.data("bs.alert",data=new Alert(this));if(typeof option=="string")data[option].call($this)})}var old=$.fn.alert;$.fn.alert=Plugin;$.fn.alert.Constructor=Alert;$.fn.alert.noConflict=function(){$.fn.alert=old;return this};$(document).on("click.bs.alert.data-api",dismiss,Alert.prototype.close)}(jQuery);+function($){"use strict";var Button=function(element,options){this.$element=$(element);this.options=$.extend({},Button.DEFAULTS,options);this.isLoading=false};Button.VERSION="3.3.5";Button.DEFAULTS={loadingText:"loading..."};Button.prototype.setState=function(state){var d="disabled";var $el=this.$element;var val=$el.is("input")?"val":"html";var data=$el.data();state+="Text";if(data.resetText==null)$el.data("resetText",$el[val]());setTimeout($.proxy(function(){$el[val](data[state]==null?this.options[state]:data[state]);if(state=="loadingText"){this.isLoading=true;$el.addClass(d).attr(d,d)}else if(this.isLoading){this.isLoading=false;$el.removeClass(d).removeAttr(d)}},this),0)};Button.prototype.toggle=function(){var changed=true;var $parent=this.$element.closest('[data-toggle="buttons"]');if($parent.length){var $input=this.$element.find("input");if($input.prop("type")=="radio"){if($input.prop("checked"))changed=false;$parent.find(".active").removeClass("active");this.$element.addClass("active")}else if($input.prop("type")=="checkbox"){if($input.prop("checked")!==this.$element.hasClass("active"))changed=false;this.$element.toggleClass("active")}$input.prop("checked",this.$element.hasClass("active"));if(changed)$input.trigger("change")}else{this.$element.attr("aria-pressed",!this.$element.hasClass("active"));this.$element.toggleClass("active")}};function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.button");var options=typeof option=="object"&&option;if(!data)$this.data("bs.button",data=new Button(this,options));if(option=="toggle")data.toggle();else if(option)data.setState(option)})}var old=$.fn.button;$.fn.button=Plugin;$.fn.button.Constructor=Button;$.fn.button.noConflict=function(){$.fn.button=old;return this};$(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(e){var $btn=$(e.target);if(!$btn.hasClass("btn"))$btn=$btn.closest(".btn");Plugin.call($btn,"toggle");if(!($(e.target).is('input[type="radio"]')||$(e.target).is('input[type="checkbox"]')))e.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){$(e.target).closest(".btn").toggleClass("focus",\/^focus(in)?$\/.test(e.type))})}(jQuery);+function($){"use strict";var Carousel=function(element,options){this.$element=$(element);this.$indicators=this.$element.find(".carousel-indicators");this.options=options;this.paused=null;this.sliding=null;this.interval=null;this.$active=null;this.$items=null;this.options.keyboard&&this.$element.on("keydown.bs.carousel",$.proxy(this.keydown,this));this.options.pause=="hover"&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",$.proxy(this.pause,this)).on("mouseleave.bs.carousel",$.proxy(this.cycle,this))};Carousel.VERSION="3.3.5";Carousel.TRANSITION_DURATION=600;Carousel.DEFAULTS={interval:5e3,pause:"hover",wrap:true,keyboard:true};Carousel.prototype.keydown=function(e){if(\/input|textarea\/i.test(e.target.tagName))return;switch(e.which){case 37:this.prev();break;case 39:this.next();break;default:return}e.preventDefault()};Carousel.prototype.cycle=function(e){e||(this.paused=false);this.interval&&clearInterval(this.interval);this.options.interval&&!this.paused&&(this.interval=setInterval($.proxy(this.next,this),this.options.interval));return this};Carousel.prototype.getItemIndex=function(item){this.$items=item.parent().children(".item");return this.$items.index(item||this.$active)};Carousel.prototype.getItemForDirection=function(direction,active){var activeIndex=this.getItemIndex(active);var willWrap=direction=="prev"&&activeIndex===0||direction=="next"&&activeIndex==this.$items.length-1;if(willWrap&&!this.options.wrap)return active;var delta=direction=="prev"?-1:1;var itemIndex=(activeIndex+delta)%this.$items.length;return this.$items.eq(itemIndex)};Carousel.prototype.to=function(pos){var that=this;var activeIndex=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(pos>this.$items.length-1||pos<0)return;if(this.sliding)return this.$element.one("slid.bs.carousel",function(){that.to(pos)});if(activeIndex==pos)return this.pause().cycle();return this.slide(pos>activeIndex?"next":"prev",this.$items.eq(pos))};Carousel.prototype.pause=function(e){e||(this.paused=true);if(this.$element.find(".next, .prev").length&&$.support.transition){this.$element.trigger($.support.transition.end);this.cycle(true)}this.interval=clearInterval(this.interval);return this};Carousel.prototype.next=function(){if(this.sliding)return;return this.slide("next")};Carousel.prototype.prev=function(){if(this.sliding)return;return this.slide("prev")};Carousel.prototype.slide=function(type,next){var $active=this.$element.find(".item.active");var $next=next||this.getItemForDirection(type,$active);var isCycling=this.interval;var direction=type=="next"?"left":"right";var that=this;if($next.hasClass("active"))return this.sliding=false;var relatedTarget=$next[0];var slideEvent=$.Event("slide.bs.carousel",{relatedTarget:relatedTarget,direction:direction});this.$element.trigger(slideEvent);if(slideEvent.isDefaultPrevented())return;this.sliding=true;isCycling&&this.pause();if(this.$indicators.length){this.$indicators.find(".active").removeClass("active");var $nextIndicator=$(this.$indicators.children()[this.getItemIndex($next)]);$nextIndicator&&$nextIndicator.addClass("active")}var slidEvent=$.Event("slid.bs.carousel",{relatedTarget:relatedTarget,direction:direction});if($.support.transition&&this.$element.hasClass("slide")){$next.addClass(type);$next[0].offsetWidth;$active.addClass(direction);$next.addClass(direction);$active.one("bsTransitionEnd",function(){$next.removeClass([type,direction].join(" ")).addClass("active");$active.removeClass(["active",direction].join(" "));that.sliding=false;setTimeout(function(){that.$element.trigger(slidEvent)},0)}).emulateTransitionEnd(Carousel.TRANSITION_DURATION)}else{$active.removeClass("active");$next.addClass("active");this.sliding=false;this.$element.trigger(slidEvent)}isCycling&&this.cycle();return this};function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.carousel");var options=$.extend({},Carousel.DEFAULTS,$this.data(),typeof option=="object"&&option);var action=typeof option=="string"?option:options.slide;if(!data)$this.data("bs.carousel",data=new Carousel(this,options));if(typeof option=="number")data.to(option);else if(action)data[action]();else if(options.interval)data.pause().cycle()})}var old=$.fn.carousel;$.fn.carousel=Plugin;$.fn.carousel.Constructor=Carousel;$.fn.carousel.noConflict=function(){$.fn.carousel=old;return this};var clickHandler=function(e){var href;var $this=$(this);var $target=$($this.attr("data-target")||(href=$this.attr("href"))&&href.replace(\/.*(?=#[^\\s]+$)\/,""));if(!$target.hasClass("carousel"))return;var options=$.extend({},$target.data(),$this.data());var slideIndex=$this.attr("data-slide-to");if(slideIndex)options.interval=false;Plugin.call($target,options);if(slideIndex){$target.data("bs.carousel").to(slideIndex)}e.preventDefault()};$(document).on("click.bs.carousel.data-api","[data-slide]",clickHandler).on("click.bs.carousel.data-api","[data-slide-to]",clickHandler);$(window).on("load",function(){$('[data-ride="carousel"]').each(function(){var $carousel=$(this);Plugin.call($carousel,$carousel.data())})})}(jQuery);+function($){"use strict";var Collapse=function(element,options){this.$element=$(element);this.options=$.extend({},Collapse.DEFAULTS,options);this.$trigger=$('[data-toggle="collapse"][href="#'+element.id+'"],'+'[data-toggle="collapse"][data-target="#'+element.id+'"]');this.transitioning=null;if(this.options.parent){this.$parent=this.getParent()}else{this.addAriaAndCollapsedClass(this.$element,this.$trigger)}if(this.options.toggle)this.toggle()};Collapse.VERSION="3.3.5";Collapse.TRANSITION_DURATION=350;Collapse.DEFAULTS={toggle:true};Collapse.prototype.dimension=function(){var hasWidth=this.$element.hasClass("width");return hasWidth?"width":"height"};Collapse.prototype.show=function(){if(this.transitioning||this.$element.hasClass("in"))return;var activesData;var actives=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(actives&&actives.length){activesData=actives.data("bs.collapse");if(activesData&&activesData.transitioning)return}var startEvent=$.Event("show.bs.collapse");this.$element.trigger(startEvent);if(startEvent.isDefaultPrevented())return;if(actives&&actives.length){Plugin.call(actives,"hide");activesData||actives.data("bs.collapse",null)}var dimension=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[dimension](0).attr("aria-expanded",true);this.$trigger.removeClass("collapsed").attr("aria-expanded",true);this.transitioning=1;var complete=function(){this.$element.removeClass("collapsing").addClass("collapse in")[dimension]("");this.transitioning=0;this.$element.trigger("shown.bs.collapse")};if(!$.support.transition)return complete.call(this);var scrollSize=$.camelCase(["scroll",dimension].join("-"));this.$element.one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])};Collapse.prototype.hide=function(){if(this.transitioning||!this.$element.hasClass("in"))return;var startEvent=$.Event("hide.bs.collapse");this.$element.trigger(startEvent);if(startEvent.isDefaultPrevented())return;var dimension=this.dimension();this.$element[dimension](this.$element[dimension]())[0].offsetHeight;this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",false);this.$trigger.addClass("collapsed").attr("aria-expanded",false);this.transitioning=1;var complete=function(){this.transitioning=0;this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};if(!$.support.transition)return complete.call(this);this.$element[dimension](0).one("bsTransitionEnd",$.proxy(complete,this)).emulateTransitionEnd(Collapse.TRANSITION_DURATION)};Collapse.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};Collapse.prototype.getParent=function(){return $(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each($.proxy(function(i,element){var $element=$(element);this.addAriaAndCollapsedClass(getTargetFromTrigger($element),$element)},this)).end()};Collapse.prototype.addAriaAndCollapsedClass=function($element,$trigger){var isOpen=$element.hasClass("in");$element.attr("aria-expanded",isOpen);$trigger.toggleClass("collapsed",!isOpen).attr("aria-expanded",isOpen)};function getTargetFromTrigger($trigger){var href;var target=$trigger.attr("data-target")||(href=$trigger.attr("href"))&&href.replace(\/.*(?=#[^\\s]+$)\/,"");return $(target)}function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.collapse");var options=$.extend({},Collapse.DEFAULTS,$this.data(),typeof option=="object"&&option);if(!data&&options.toggle&&\/show|hide\/.test(option))options.toggle=false;if(!data)$this.data("bs.collapse",data=new Collapse(this,options));if(typeof option=="string")data[option]()})}var old=$.fn.collapse;$.fn.collapse=Plugin;$.fn.collapse.Constructor=Collapse;$.fn.collapse.noConflict=function(){$.fn.collapse=old;return this};$(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(e){var $this=$(this);if(!$this.attr("data-target"))e.preventDefault();var $target=getTargetFromTrigger($this);var data=$target.data("bs.collapse");var option=data?"toggle":$this.data();Plugin.call($target,option)})}(jQuery);+function($){"use strict";var backdrop=".dropdown-backdrop";var toggle='[data-toggle="dropdown"]';var Dropdown=function(element){$(element).on("click.bs.dropdown",this.toggle)};Dropdown.VERSION="3.3.5";function getParent($this){var selector=$this.attr("data-target");if(!selector){selector=$this.attr("href");selector=selector&&\/#[A-Za-z]\/.test(selector)&&selector.replace(\/.*(?=#[^\\s]*$)\/,"")}var $parent=selector&&$(selector);return $parent&&$parent.length?$parent:$this.parent()}function clearMenus(e){if(e&&e.which===3)return;$(backdrop).remove();$(toggle).each(function(){var $this=$(this);var $parent=getParent($this);var relatedTarget={relatedTarget:this};if(!$parent.hasClass("open"))return;if(e&&e.type=="click"&&\/input|textarea\/i.test(e.target.tagName)&&$.contains($parent[0],e.target))return;$parent.trigger(e=$.Event("hide.bs.dropdown",relatedTarget));if(e.isDefaultPrevented())return;$this.attr("aria-expanded","false");$parent.removeClass("open").trigger("hidden.bs.dropdown",relatedTarget)})}Dropdown.prototype.toggle=function(e){var $this=$(this);if($this.is(".disabled, :disabled"))return;var $parent=getParent($this);var isActive=$parent.hasClass("open");clearMenus();if(!isActive){if("ontouchstart"in document.documentElement&&!$parent.closest(".navbar-nav").length){$(document.createElement("div")).addClass("dropdown-backdrop").insertAfter($(this)).on("click",clearMenus)}var relatedTarget={relatedTarget:this};$parent.trigger(e=$.Event("show.bs.dropdown",relatedTarget));if(e.isDefaultPrevented())return;$this.trigger("focus").attr("aria-expanded","true");$parent.toggleClass("open").trigger("shown.bs.dropdown",relatedTarget)}return false};Dropdown.prototype.keydown=function(e){if(!\/(38|40|27|32)\/.test(e.which)||\/input|textarea\/i.test(e.target.tagName))return;var $this=$(this);e.preventDefault();e.stopPropagation();if($this.is(".disabled, :disabled"))return;var $parent=getParent($this);var isActive=$parent.hasClass("open");if(!isActive&&e.which!=27||isActive&&e.which==27){if(e.which==27)$parent.find(toggle).trigger("focus");return $this.trigger("click")}var desc=" li:not(.disabled):visible a";var $items=$parent.find(".dropdown-menu"+desc);if(!$items.length)return;var index=$items.index(e.target);if(e.which==38&&index>0)index--;if(e.which==40&&index<$items.length-1)index++;if(!~index)index=0;$items.eq(index).trigger("focus")};function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.dropdown");if(!data)$this.data("bs.dropdown",data=new Dropdown(this));if(typeof option=="string")data[option].call($this)})}var old=$.fn.dropdown;$.fn.dropdown=Plugin;$.fn.dropdown.Constructor=Dropdown;$.fn.dropdown.noConflict=function(){$.fn.dropdown=old;return this};$(document).on("click.bs.dropdown.data-api",clearMenus).on("click.bs.dropdown.data-api",".dropdown form",function(e){e.stopPropagation()}).on("click.bs.dropdown.data-api",toggle,Dropdown.prototype.toggle).on("keydown.bs.dropdown.data-api",toggle,Dropdown.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",Dropdown.prototype.keydown)}(jQuery);+function($){"use strict";var Modal=function(element,options){this.options=options;this.$body=$(document.body);this.$element=$(element);this.$dialog=this.$element.find(".modal-dialog");this.$backdrop=null;this.isShown=null;this.originalBodyPad=null;this.scrollbarWidth=0;this.ignoreBackdropClick=false;if(this.options.remote){this.$element.find(".modal-content").load(this.options.remote,$.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))}};Modal.VERSION="3.3.5";Modal.TRANSITION_DURATION=300;Modal.BACKDROP_TRANSITION_DURATION=150;Modal.DEFAULTS={backdrop:true,keyboard:true,show:true};Modal.prototype.toggle=function(_relatedTarget){return this.isShown?this.hide():this.show(_relatedTarget)};Modal.prototype.show=function(_relatedTarget){var that=this;var e=$.Event("show.bs.modal",{relatedTarget:_relatedTarget});this.$element.trigger(e);if(this.isShown||e.isDefaultPrevented())return;this.isShown=true;this.checkScrollbar();this.setScrollbar();this.$body.addClass("modal-open");this.escape();this.resize();this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',$.proxy(this.hide,this));this.$dialog.on("mousedown.dismiss.bs.modal",function(){that.$element.one("mouseup.dismiss.bs.modal",function(e){if($(e.target).is(that.$element))that.ignoreBackdropClick=true})});this.backdrop(function(){var transition=$.support.transition&&that.$element.hasClass("fade");if(!that.$element.parent().length){that.$element.appendTo(that.$body)}that.$element.show().scrollTop(0);that.adjustDialog();if(transition){that.$element[0].offsetWidth}that.$element.addClass("in");that.enforceFocus();var e=$.Event("shown.bs.modal",{relatedTarget:_relatedTarget});transition?that.$dialog.one("bsTransitionEnd",function(){that.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(Modal.TRANSITION_DURATION):that.$element.trigger("focus").trigger(e)})};Modal.prototype.hide=function(e){if(e)e.preventDefault();e=$.Event("hide.bs.modal");this.$element.trigger(e);if(!this.isShown||e.isDefaultPrevented())return;this.isShown=false;this.escape();this.resize();$(document).off("focusin.bs.modal");this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal");this.$dialog.off("mousedown.dismiss.bs.modal");$.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",$.proxy(this.hideModal,this)).emulateTransitionEnd(Modal.TRANSITION_DURATION):this.hideModal()};Modal.prototype.enforceFocus=function(){$(document).off("focusin.bs.modal").on("focusin.bs.modal",$.proxy(function(e){if(this.$element[0]!==e.target&&!this.$element.has(e.target).length){this.$element.trigger("focus")}},this))};Modal.prototype.escape=function(){if(this.isShown&&this.options.keyboard){this.$element.on("keydown.dismiss.bs.modal",$.proxy(function(e){e.which==27&&this.hide()},this))}else if(!this.isShown){this.$element.off("keydown.dismiss.bs.modal")}};Modal.prototype.resize=function(){if(this.isShown){$(window).on("resize.bs.modal",$.proxy(this.handleUpdate,this))}else{$(window).off("resize.bs.modal")}};Modal.prototype.hideModal=function(){var that=this;this.$element.hide();this.backdrop(function(){that.$body.removeClass("modal-open");that.resetAdjustments();that.resetScrollbar();that.$element.trigger("hidden.bs.modal")})};Modal.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove();this.$backdrop=null};Modal.prototype.backdrop=function(callback){var that=this;var animate=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var doAnimate=$.support.transition&&animate;this.$backdrop=$(document.createElement("div")).addClass("modal-backdrop "+animate).appendTo(this.$body);this.$element.on("click.dismiss.bs.modal",$.proxy(function(e){if(this.ignoreBackdropClick){this.ignoreBackdropClick=false;return}if(e.target!==e.currentTarget)return;this.options.backdrop=="static"?this.$element[0].focus():this.hide()},this));if(doAnimate)this.$backdrop[0].offsetWidth;this.$backdrop.addClass("in");if(!callback)return;doAnimate?this.$backdrop.one("bsTransitionEnd",callback).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callback()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var callbackRemove=function(){that.removeBackdrop();callback&&callback()};$.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",callbackRemove).emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION):callbackRemove()}else if(callback){callback()}};Modal.prototype.handleUpdate=function(){this.adjustDialog()};Modal.prototype.adjustDialog=function(){var modalIsOverflowing=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&modalIsOverflowing?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!modalIsOverflowing?this.scrollbarWidth:""})};Modal.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})};Modal.prototype.checkScrollbar=function(){var fullWindowWidth=window.innerWidth;if(!fullWindowWidth){var documentElementRect=document.documentElement.getBoundingClientRect();fullWindowWidth=documentElementRect.right-Math.abs(documentElementRect.left)}this.bodyIsOverflowing=document.body.clientWidth
<\/div>
<\/div><\/div>',trigger:"hover focus",title:"",delay:0,html:false,container:false,viewport:{selector:"body",padding:0}};Tooltip.prototype.init=function(type,element,options){this.enabled=true;this.type=type;this.$element=$(element);this.options=this.getOptions(options);this.$viewport=this.options.viewport&&$($.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport);this.inState={click:false,hover:false,focus:false};if(this.$element[0]instanceof document.constructor&&!this.options.selector){throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!")}var triggers=this.options.trigger.split(" ");for(var i=triggers.length;i--;){var trigger=triggers[i];if(trigger=="click"){this.$element.on("click."+this.type,this.options.selector,$.proxy(this.toggle,this))}else if(trigger!="manual"){var eventIn=trigger=="hover"?"mouseenter":"focusin";var eventOut=trigger=="hover"?"mouseleave":"focusout";this.$element.on(eventIn+"."+this.type,this.options.selector,$.proxy(this.enter,this));this.$element.on(eventOut+"."+this.type,this.options.selector,$.proxy(this.leave,this))}}this.options.selector?this._options=$.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()};Tooltip.prototype.getDefaults=function(){return Tooltip.DEFAULTS};Tooltip.prototype.getOptions=function(options){options=$.extend({},this.getDefaults(),this.$element.data(),options);if(options.delay&&typeof options.delay=="number"){options.delay={show:options.delay,hide:options.delay}}return options};Tooltip.prototype.getDelegateOptions=function(){var options={};var defaults=this.getDefaults();this._options&&$.each(this._options,function(key,value){if(defaults[key]!=value)options[key]=value});return options};Tooltip.prototype.enter=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);if(!self){self=new this.constructor(obj.currentTarget,this.getDelegateOptions());$(obj.currentTarget).data("bs."+this.type,self)}if(obj instanceof $.Event){self.inState[obj.type=="focusin"?"focus":"hover"]=true}if(self.tip().hasClass("in")||self.hoverState=="in"){self.hoverState="in";return}clearTimeout(self.timeout);self.hoverState="in";if(!self.options.delay||!self.options.delay.show)return self.show();self.timeout=setTimeout(function(){if(self.hoverState=="in")self.show()},self.options.delay.show)};Tooltip.prototype.isInStateTrue=function(){for(var key in this.inState){if(this.inState[key])return true}return false};Tooltip.prototype.leave=function(obj){var self=obj instanceof this.constructor?obj:$(obj.currentTarget).data("bs."+this.type);if(!self){self=new this.constructor(obj.currentTarget,this.getDelegateOptions());$(obj.currentTarget).data("bs."+this.type,self)}if(obj instanceof $.Event){self.inState[obj.type=="focusout"?"focus":"hover"]=false}if(self.isInStateTrue())return;clearTimeout(self.timeout);self.hoverState="out";if(!self.options.delay||!self.options.delay.hide)return self.hide();self.timeout=setTimeout(function(){if(self.hoverState=="out")self.hide()},self.options.delay.hide)};Tooltip.prototype.show=function(){var e=$.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var inDom=$.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!inDom)return;var that=this;var $tip=this.tip();var tipId=this.getUID(this.type);this.setContent();$tip.attr("id",tipId);this.$element.attr("aria-describedby",tipId);if(this.options.animation)$tip.addClass("fade");var placement=typeof this.options.placement=="function"?this.options.placement.call(this,$tip[0],this.$element[0]):this.options.placement;var autoToken=\/\\s?auto?\\s?\/i;var autoPlace=autoToken.test(placement);if(autoPlace)placement=placement.replace(autoToken,"")||"top";$tip.detach().css({top:0,left:0,display:"block"}).addClass(placement).data("bs."+this.type,this);this.options.container?$tip.appendTo(this.options.container):$tip.insertAfter(this.$element);this.$element.trigger("inserted.bs."+this.type);var pos=this.getPosition();var actualWidth=$tip[0].offsetWidth;var actualHeight=$tip[0].offsetHeight;if(autoPlace){var orgPlacement=placement;var viewportDim=this.getPosition(this.$viewport);placement=placement=="bottom"&&pos.bottom+actualHeight>viewportDim.bottom?"top":placement=="top"&&pos.top-actualHeightviewportDim.width?"left":placement=="left"&&pos.left-actualWidthviewportDimensions.top+viewportDimensions.height){delta.top=viewportDimensions.top+viewportDimensions.height-bottomEdgeOffset}}else{var leftEdgeOffset=pos.left-viewportPadding;var rightEdgeOffset=pos.left+viewportPadding+actualWidth;if(leftEdgeOffsetviewportDimensions.right){delta.left=viewportDimensions.left+viewportDimensions.width-rightEdgeOffset}}return delta};Tooltip.prototype.getTitle=function(){var title;var $e=this.$element;var o=this.options;title=$e.attr("data-original-title")||(typeof o.title=="function"?o.title.call($e[0]):o.title);return title};Tooltip.prototype.getUID=function(prefix){do prefix+=~~(Math.random()*1e6);while(document.getElementById(prefix));return prefix};Tooltip.prototype.tip=function(){if(!this.$tip){this.$tip=$(this.options.template);if(this.$tip.length!=1){throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!")}}return this.$tip};Tooltip.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")};Tooltip.prototype.enable=function(){this.enabled=true};Tooltip.prototype.disable=function(){this.enabled=false};Tooltip.prototype.toggleEnabled=function(){this.enabled=!this.enabled};Tooltip.prototype.toggle=function(e){var self=this;if(e){self=$(e.currentTarget).data("bs."+this.type);if(!self){self=new this.constructor(e.currentTarget,this.getDelegateOptions());$(e.currentTarget).data("bs."+this.type,self)}}if(e){self.inState.click=!self.inState.click;if(self.isInStateTrue())self.enter(self);else self.leave(self)}else{self.tip().hasClass("in")?self.leave(self):self.enter(self)}};Tooltip.prototype.destroy=function(){var that=this;clearTimeout(this.timeout);this.hide(function(){that.$element.off("."+that.type).removeData("bs."+that.type);if(that.$tip){that.$tip.detach()}that.$tip=null;that.$arrow=null;that.$viewport=null})};function Plugin(option){return this.each(function(){var $this=$(this);var data=$this.data("bs.tooltip");var options=typeof option=="object"&&option;if(!data&&\/destroy|hide\/.test(option))return;if(!data)$this.data("bs.tooltip",data=new Tooltip(this,options));if(typeof option=="string")data[option]()})}var old=$.fn.tooltip;$.fn.tooltip=Plugin;$.fn.tooltip.Constructor=Tooltip;$.fn.tooltip.noConflict=function(){$.fn.tooltip=old;return this}}(jQuery);+function($){"use strict";var Popover=function(element,options){this.init("popover",element,options)};if(!$.fn.tooltip)throw new Error("Popover requires tooltip.js");Popover.VERSION="3.3.5";Popover.DEFAULTS=$.extend({},$.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'