Add files via upload
diff --git a/graf.php b/graf.php
index e965a00..58f5ed6 100644
--- a/graf.php
+++ b/graf.php
@@ -21,8 +21,9 @@
 
     <meta name=viewport content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
     <link rel="manifest" href="manifest.json">
-
-    <link rel="stylesheet" href="css/styles.css">
+    
+    <!-- <link rel="stylesheet" href="css/styles.css"> -->
+    <!-- PER DEBUGAR --> <link rel="stylesheet" href="styles_debug.css">
 
     <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
     <link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.blue_grey-blue.min.css" />
@@ -34,10 +35,13 @@
     <meta name="apple-mobile-web-app-status-bar-style" content="black">
   </head>
   <body>
+  <button id="settings" class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored"><i class="material-icons">settings</i></button>
     <button id="search" class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored"><i class="material-icons">search</i></button>
     <button id="zoomin" class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored"><i class="material-icons">zoom_in</i></button>
     <button id="zoomout" class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored"><i class="material-icons">zoom_out</i></button>
 
+  <div id="yearlist" style="padding:10px; padding-top:70px; float:right; display: none"> </div>
+
     <div id="backdrop-container" style="display: none;">
       <div id="backdrop"></div>
     </div>
@@ -88,13 +92,14 @@
     </div>
 
     <div id="graf"></div>
-
+  
     <script src="https://cdnjs.cloudflare.com/ajax/libs/sigma.js/1.2.0/sigma.min.js"></script>
 
     <!-- Search Bar JS files -->
     <script src="./js/autocomplete.js" ></script>
 
-	   <script src="js/script.js"></script>
+    <!-- <script src="js/script.js"></script> -->
+    <!-- PER DEBUGAR --> <script src="script_debug.js"></script>
 
     <script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
     <!--<script src="js/service-worker.js"></script>-->
diff --git a/script_debug.js b/script_debug.js
new file mode 100644
index 0000000..19405d1
--- /dev/null
+++ b/script_debug.js
@@ -0,0 +1,326 @@
+var s, graf;
+
+var showYears = new Set();
+var limitYears = false;
+
+function xhr(method, url, params, callback) {
+  var http = new XMLHttpRequest();
+  if (method == "POST") {
+    http.open(method, url, true);
+  } else {
+    if (params != "") {
+      http.open(method, url+"?"+params, true);
+    } else {
+      http.open(method, url, true);
+    }
+  }
+  http.onload = function() {
+    if(this.status != 200) {
+      console.warn("Attention, status code "+this.status+" when loading via xhr url "+url);
+    }
+    callback(this.responseText, this.status);
+  };
+  if (method == "POST") {
+    http.setRequestHeader("Content-type","application/x-www-form-urlencoded");
+    http.send(params);
+  } else {
+    http.send();
+  }
+}
+
+function altSearchBar() {
+  if (document.querySelector(".md-google-search__metacontainer").style.display == "none") {
+    document.querySelector(".md-google-search__metacontainer").style.display = "block";
+    document.querySelector("#search i").innerText = "fullscreen";
+  } else {
+    document.querySelector(".md-google-search__metacontainer").style.display = "none";
+    document.querySelector(".autocomplete-container").style.display = "none";
+    document.querySelector("#search i").innerText = "search";
+  }
+}
+
+var seq = [38, 38, 40, 40, 37, 39, 37, 39, 65, 66, 13];
+var cur = 0;
+
+
+function repaint() {
+  if(limitYears) {
+    s.graph.nodes().forEach(function(n) {
+      if (!showYears.has("" + n.year)) {
+        n.hidden = true;
+      }
+      else {
+    	  n.hidden = false;
+      }
+    });
+    
+    s.graph.edges().forEach(function(e) {
+      if(!showYears.has(""+e.sourceyear) || !showYears.has(""+e.targetyear)){
+    	  e.hidden = true;
+      }
+      else e.hidden = false;
+    }); 
+  }
+  else {
+    s.graph.nodes().forEach(function(n) {
+    	n.hidden = false;
+    });
+    
+    s.graph.edges().forEach(function(e) {
+    	e.hidden = false;
+    });
+  }
+}
+
+function justdoit() {
+  s.graph.nodes().forEach(function(n) {
+    switch(n.color) {
+      case "#d61c08":
+      n.color = "#0159aa";
+      break;
+
+      case "#0159aa":
+      n.color = "#0ca80a";
+      break;
+
+      case "#0ca80a":
+      n.color = "#d61c08";
+      break;
+    }
+  });
+
+  s.refresh();
+  setTimeout(justdoit, 333);
+}
+
+var dialog = {
+  fill: function(data, text, html=false) {
+    var el = document.querySelectorAll("*[data-fill=\""+data+"\"]");
+    for (var i in el) {
+      if (html === true) {
+        el[i].innerHTML = text;
+      } else {
+        el[i].innerText = text;
+      }
+    }
+  },
+  show: function(id, neighbors) {
+    var neighbors = Object.values(neighbors);
+
+    this.fill("name", graf.nodes[id].name);
+    this.fill("year", graf.nodes[id].year);
+    this.fill("sex", graf.nodes[id].sex);
+    this.fill("id", "#"+id);
+    this.fill("n-edges", neighbors.length);
+
+    var list = "";
+    neighbors.forEach(function (a) {
+      list += "<li><b>"+graf.nodes[id].name+" - "+a.label+":</b> "+(graf.edges[id+"_"+a.id] ? graf.edges[id+"_"+a.id].votes : graf.edges[a.id+"_"+id].votes)+" vots</li>";
+    });
+    this.fill("edges", list, true);
+
+    if (window.innerWidth > 700) {
+      document.querySelector("#dialog").style.display = "block";
+      document.querySelector("#backdrop-container").style.display = "block";
+    } else {
+      document.querySelector("#summary-dialog").style.display = "block";
+    }
+  },
+  close: function() {
+    document.querySelector("#dialog").style.display = "none";
+    document.querySelector("#summary-dialog").style.display = "none";
+    document.querySelector("#backdrop-container").style.display = "none";
+    
+    repaint();
+
+    s.refresh();
+  },
+  max: function() {
+    document.querySelector("#summary-dialog").style.display = "none";
+    document.querySelector("#dialog").style.display = "block";
+  },
+  min: function() {
+    document.querySelector("#dialog").style.display = "none";
+    document.querySelector("#summary-dialog").style.display = "block";
+  }
+};
+
+function init() {
+  sigma.classes.graph.addMethod("neighbors", function(nodeId) {
+    var k,
+        neighbors = {},
+        index = this.allNeighborsIndex[nodeId] || [];
+
+    for (k in index) {
+      neighbors[k] = this.nodesIndex[k];
+    }
+
+    return neighbors;
+  });
+
+  s = new sigma({
+    renderers: [{
+      container: "graf",
+      type: "webgl"
+    }],
+    settings: {
+      defaultEdgeColor: "#fff",
+      edgeColor: "default",
+      defaultLabelColor: "#fff",
+      autoRescale: false,
+      zoomMax: 10,
+      //enableEdgeHovering: true,
+      font: "Roboto",
+      labelThreshold: 5
+    }
+  });
+
+  xhr("GET", "api.php", "action=getgraf", function(responseText, status) {
+    graf = JSON.parse(responseText);
+
+    console.log(graf);
+
+    for (var i in graf.nodes) {
+      var ncolor = (graf.nodes[i].sex == "F" ? "#d61c08" : (graf.nodes[i].sex == "M" ? "#0159aa" : "#0ca80a"));
+
+  s.graph.addNode({
+    id: graf.nodes[i].id,
+    year: graf.nodes[i].year,
+    label: graf.nodes[i].name,
+    x: graf.nodes[i].x,
+    y: graf.nodes[i].y,
+    size: 10,
+    color: ncolor,
+    originalColor: ncolor
+  });
+  }
+
+  for (var i in graf.edges) {
+    s.graph.addEdge({
+      id: i,
+      source: graf.edges[i].a,
+      target: graf.edges[i].b,
+      sourceyear: graf.nodes[graf.edges[i].a].year,
+      targetyear: graf.nodes[graf.edges[i].b].year,
+      size: Math.min(4, Math.max((7/(2*Math.pow(20, 2)))*Math.pow(graf.edges[i].votes, 2) + 1/2, 0.5))
+    });
+  }
+  s.bind('clickNode', function(e) {
+    var nodeId = e.data.node.id,
+      toKeep = s.graph.neighbors(nodeId);
+      //toKeep[nodeId] = e.data.node;
+
+      s.graph.nodes().forEach(function(n) {
+        if (toKeep[n.id] || n.id == nodeId) {
+          n.color = n.originalColor;
+        } else {
+          n.color = '#333';
+        }
+      });
+
+      s.graph.edges().forEach(function(e) {
+        if ((e.source == nodeId || e.target == nodeId) && (toKeep[e.source] || toKeep[e.target])) {
+          e.color = '#fff';
+        } else {
+          e.color = '#333';
+        }
+      });
+
+      s.refresh();
+
+      dialog.show(nodeId, toKeep);
+    });
+
+    document.querySelector("#quit-dialog").addEventListener("click", dialog.close);
+    document.querySelector("#quit2-dialog").addEventListener("click", dialog.close);
+    document.querySelector("#max-dialog").addEventListener("click", dialog.max);
+    document.querySelector("#min-dialog").addEventListener("click", dialog.min);
+
+    document.querySelector("#zoomin").addEventListener("click", function() {
+      s.camera.goTo({
+        ratio: Math.max(s.camera.settings("zoomMin"), s.camera.ratio / Math.sqrt(2))
+      });
+    });
+
+    document.querySelector("#zoomout").addEventListener("click", function() {
+      s.camera.goTo({
+        ratio: Math.min(s.camera.settings("zoomMax"), s.camera.ratio * Math.sqrt(2))
+      });
+    });
+
+    var ylist = document.querySelector("#yearlist");
+    var enc = document.createElement("span");
+    for(var year=2006; year<2019; year++) {
+      
+      var yin = document.createElement("input");
+      yin.type = "checkbox";
+      yin.class = "mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored";
+      yin.name = "" + year;
+      yin.addEventListener("change", function(){ 
+      limitYears = true;
+        
+      if(this.checked) {
+        showYears.add(this.name);
+      }
+      else {
+        showYears.delete(this.name);
+      }
+      
+      if(showYears.size == 0) limitYears = false;
+        
+      repaint();
+      
+      s.refresh();
+      });
+      
+      var lab = document.createElement("label");
+      lab.innerHTML = "" + year + "<br>";
+
+      enc.appendChild(yin);
+      enc.appendChild(lab);
+    }
+    ylist.appendChild(enc);
+    
+    document.querySelector("#settings").addEventListener("click", function() {
+      var yearlist = document.querySelector("#yearlist");
+      
+      if(yearlist.style.display == "none"){
+      yearlist.style.display = "block";
+      yearLimits = true;
+      }
+      else{
+      yearlist.style.display = "none";
+      yearLimits = true;
+      }
+    });
+    
+    document.addEventListener("keydown", function() {
+      
+      if (event.key == "f" && event.target.getAttribute("id") != "search-input") altSearchBar();
+      if (event.which == seq[cur]) {
+        if (cur < seq.length) {
+          ++cur;
+          if (cur == seq.length) {
+            justdoit();
+          }
+        }
+      } else cur = 0;
+    })
+    document.querySelector("#search").addEventListener("click", altSearchBar);
+
+    if (window.innerWidth > 700) altSearchBar();
+
+    s.refresh();
+    autocomplete(document.querySelector("#search-input"), graf.nodes, "search");
+  });
+}
+
+function cameraGoto(nodeX, nodeY) {
+  sigma.misc.animation.camera( s.camera,
+    { x: nodeX, y: nodeY, ratio: 1 },
+    { duration: s.settings('animationsTime') || 300 }
+  );
+}
+
+window.addEventListener("load", init);
+
diff --git a/styles_debug.css b/styles_debug.css
new file mode 100644
index 0000000..15c39c0
--- /dev/null
+++ b/styles_debug.css
@@ -0,0 +1,277 @@
+html, body {
+  margin: 0;
+  width: 100%;
+  height: 100%;
+  background-color: #060606;
+  color: white;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+  user-select: none!important;
+  font-family: 'Roboto';
+}
+
+#graf {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  z-index: 1;
+}
+
+canvas {
+  position: absolute;
+  z-index: 2;
+}
+span {
+  position: relative;
+  z-index: 3
+}
+
+#dialog {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  width: 300px;
+  height: 100%;
+  background-color: white;
+  color: black;
+  z-index: 120;
+  overflow-y: auto;
+}
+
+#backdrop {
+  display: none;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, .5);
+  z-index: 110;
+}
+
+#dialog-vertex, #dialog-edge{
+  padding: 8px;
+  user-select: auto;
+}
+
+#dialog h2 {
+  font-weight: bold;
+  font-size: 20px;
+}
+
+#dialog h3 {
+  font-weight: bold;
+  font-size: 16px;
+  margin-bottom: 0;
+}
+
+#quit-dialog, #quit2-dialog {
+  position: absolute;
+  top: 8px;
+  right: 8px;
+}
+
+#min-dialog, #max-dialog {
+  position: absolute;
+  top: 8px;
+  right: 48px;
+}
+
+#min-dialog {
+  display: none;
+}
+
+#summary-dialog {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+  width: 100%;
+  height: 100px;
+  background-color: white;
+  color: black;
+  z-index: 120;
+}
+
+#summary-vertex {
+  padding: 8px;
+  user-select: auto;
+}
+
+#summary-dialog h2 {
+  font-weight: bold;
+  font-size: 20px;
+  margin: 0;
+}
+
+#settings {
+  position: absolute;
+  right: 10px;
+  bottom: 160px;
+  z-index: 100;
+}
+
+#search {
+  position: absolute;
+  right: 10px;
+  bottom: 110px;
+  z-index: 100;
+}
+
+#zoomin {
+  position: absolute;
+  right: 10px;
+  bottom: 60px;
+  z-index: 100;
+}
+
+#zoomout {
+  position: absolute;
+  right: 10px;
+  bottom: 10px;
+  z-index: 100;
+}
+
+input {
+  z-index: 100;
+}
+
+label {
+  z-index: 100;
+}
+
+/**
+  * MD search box
+  */
+.md-google-search__metacontainer {
+  position: absolute;
+  top: 10px;
+  height: 48px;
+  width: 100%;
+  z-index: 100;
+}
+
+.md-google-search__container {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  height: 48px;
+  width: Calc(100% - 66px);
+  max-width: 720px;
+  white-space: nowrap;
+}
+
+.md-google-search {
+  height: 48px;
+  background-color: rgba(245,245,245,1);
+  border: 1px solid rgba(0,0,0,0);
+  -webkit-border-radius: 4px;
+  border-radius: 4px;
+  max-width: 720px;
+  position: relative;
+  -webkit-transition: background-color 100ms ease-in,width 100ms ease-out;
+  transition: background-color 100ms ease-in,width 100ms ease-out;
+}
+
+.md-google-search:focus-within {
+  border: 1px solid rgba(0,0,0,0.45);
+  background-color: rgba(255,255,255,1);
+  -webkit-box-shadow: 0 1px 1px rgba(255,255,255,.5);
+  box-shadow: 0 1px 1px rgba(255,255,255,.5);
+}
+
+.md-google-search__search-btn {
+  float: left;
+  background: none;
+  border: none;
+  opacity: .54;
+  outline: none;
+  padding: 0 4px;
+  line-height: 0;
+  color: #212121;
+}
+
+.md-google-search__search-btn svg, .md-google-search__empty-btn svg {
+  padding: 7px;
+  margin: 4px;
+}
+
+.md-google-search__field-container {
+  height: 46px;
+  padding: 0 11px;
+  margin-right: 48px;
+}
+
+.md-google-search__field {
+  border: none;
+  font: normal 16px Roboto,sans-serif;
+  height: 24px;
+  outline: none;
+  padding: 11px 0 11px 16px;
+  width: 100%;
+  background: transparent;
+}
+
+.md-google-search__empty-btn {
+  position: absolute;
+  right: 0;
+  top: 0;
+  background: none;
+  border: none;
+  opacity: .54;
+  outline: none;
+  padding: 0 4px;
+  line-height: 0;
+  color: #212121;
+  cursor: pointer;
+}
+
+/**
+  * Search Box Autocomplete
+  */
+
+.autocomplete-container{
+  z-index: 110;
+  position: absolute;
+  top: 60px;
+  width: 100%;
+}
+
+.autocomplete-items {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+  width: Calc(100% - 66px);
+  max-width: 720px;
+  background-color: white;
+  color: black;
+  box-shadow: 0 2px 5px 0 rgba(255,255,255,0.258824),0 2px 10px 0 rgba(255,255,255,0.156863) !important;
+}
+
+.autocomplete-item {
+  font-size: 16px;
+  padding: 12px 14px;
+  cursor: pointer;
+}
+
+.autocomplete-item:hover, .autocomplete-active {
+  background: #eee;
+}
+
+.autocomplete-year {
+  color: #222;
+}
+
+@media (max-width: 700px) {
+  #dialog {
+    width: Calc(100% - 32px)!important;
+    height: Calc(100% - 32px)!important;
+    margin: 16px;
+  }
+
+  #backdrop {
+    display: block;
+  }
+
+  #min-dialog {
+    display: block!important;
+  }
+}