diff --git a/README.md b/README.md
index 74825e8419..5cc77912d5 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,17 @@
[](https://travis-ci.org/pandorafms/pandorafms)
-[](http://pandorafms.org)
+
-Pandora FMS is a monitoring software for IT infrastructure management which includes network equipment, Windows and Unix servers, virtual infrastructure and all different kind of applications. It has a large amount of features, making it a new generation software which discovers all the monitoring issues that an organization may need.
+
+With more than 50,000 customer installations across the five continents, Pandora FMS is an out-of-the-box monitoring solution: profitable and scalable, covering most infrastructure deployment options.
+
+Pandora FMS gives you the agility to find and solve problems quickly, scaling them so they can be derived from any source, on-premise, multi cloud or both of them mixed. Now you have that capability across your entire IT stack and analytics to find any problem, even the ones that are hard to find.
+
+Thanks to more than 500 plugins available, you can control and manage any application and technology, from SAP, Oracle, Lotus, Citrix or Jboss to VMware, AWS, SQL Server, Redhat, Websphere, etc.
### Support
-For community support you can visit our forums at http://forums.pandorafms.org. Visit our community page at http://pandorafms.org and if you need commercial information or/and professional support visit http://pandorafms.com.
+For community support you can visit our forums at https://pandorafms.com/community/ and if you need commercial information or/and professional support visit https://pandorafms.com
### How to install Pandora FMS
diff --git a/extras/PandoraFMS_android_console/src/pandorafms/pandorafmsandroidconsole/PandoraWebView.java b/extras/PandoraFMS_android_console/src/pandorafms/pandorafmsandroidconsole/PandoraWebView.java
index 13e28af1ea..4c566ff0f4 100644
--- a/extras/PandoraFMS_android_console/src/pandorafms/pandorafmsandroidconsole/PandoraWebView.java
+++ b/extras/PandoraFMS_android_console/src/pandorafms/pandorafmsandroidconsole/PandoraWebView.java
@@ -88,7 +88,7 @@ public class PandoraWebView extends Activity {
//Check the first load the page for to hide a toast with the
//connection message
- //Close the CustomToast (I love this hack, fuck javalovers and yours patterns.).
+ //Close the CustomToast.
if (ConnectionCustomToast.activity != null)
ConnectionCustomToast.activity.finish();
}
diff --git a/extras/cats.html b/extras/cats.html
index 8da94e3e5e..ba399ca65e 100644
--- a/extras/cats.html
+++ b/extras/cats.html
@@ -1,428 +1,479 @@
-
- gatete
-
-
-
-
-
+
+
+
+
-var svg = d3.select("#test svg");
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+ svg
+ .append("g")
+ .attr("id", "circulo")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_center_element("#cat1")[0] +
+ " " +
+ get_center_element("#cat1")[1] +
+ ")"
+ );
+ })
+ .append("circle")
+ .attr("style", "fill: rgb(0, 255, 0);")
+ .attr("cx", 0)
+ .attr("cy", 0)
+ .attr("r", 20);
+
+ svg
+ .append("g")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_pos_element("#cat1")[0] +
+ " " +
+ get_pos_element("#cat1")[1] +
+ ") scale(" +
+ get_scale_element("#cat1") +
+ ")"
+ );
+ })
+ .append("rect")
+ .attr("style", "fill:none; stroke:#ffff00;stroke-width:5")
+ .attr("width", function(d) {
+ return get_size_element("#cat1")[0];
+ })
+ .attr("height", function(d) {
+ return get_size_element("#cat1")[1];
+ });
+
+ svg
+ .append("g")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_center_element("#cat1")[0] +
+ " " +
+ get_center_element("#cat1")[1] +
+ ") scale(" +
+ get_scale_element("#cat1") +
+ ")"
+ );
+ })
+ .append("circle")
+ .attr("style", "fill: none; stroke-width: 5; stroke: rgb(0, 0, 255);")
+ .attr("cx", 0)
+ .attr("cy", 0)
+ .attr("r", get_radius_element("#cat1"));
+
+ svg
+ .append("g")
+ .attr("id", "circulo")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_center_element("#cat3")[0] +
+ " " +
+ get_center_element("#cat3")[1] +
+ ")"
+ );
+ })
+ .append("circle")
+ .attr("style", "fill: rgb(0, 255, 0);")
+ .attr("cx", 0)
+ .attr("cy", 0)
+ .attr("r", 20);
+
+ svg
+ .append("g")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_pos_element("#cat3")[0] +
+ " " +
+ get_pos_element("#cat3")[1] +
+ ") scale(" +
+ get_scale_element("#cat3") +
+ ")"
+ );
+ })
+ .append("rect")
+ .attr("style", "fill:none; stroke:#ffff00;stroke-width:5")
+ .attr("width", function(d) {
+ return get_size_element("#cat3")[0];
+ })
+ .attr("height", function(d) {
+ return get_size_element("#cat3")[1];
+ });
+
+ svg
+ .append("g")
+ .attr("transform", function(d) {
+ return (
+ "translate(" +
+ get_center_element("#cat3")[0] +
+ " " +
+ get_center_element("#cat3")[1] +
+ ") scale(" +
+ get_scale_element("#cat3") +
+ ")"
+ );
+ })
+ .append("circle")
+ .attr("style", "fill: none; stroke-width: 5; stroke: rgb(0, 0, 255);")
+ .attr("cx", 0)
+ .attr("cy", 0)
+ .attr("r", get_radius_element("#cat3"));
+
+ arrow_by_pieces2("gatete_flecha", "cat1", "cat2");
+ arrow_by_pieces2("gatete_flecha2", "cat1", "cat4");
+ arrow_by_pieces2("gatete_flecha3", "cat3", "cat4");
+
+ //~ arrow_by_pieces("gatete_flecha", "cat1", "cat2");
+ //~ arrow_by_pieces("gatete_flecha", "cat3", "cat4");
+
+ /**
+ * Function get_radius_element
+ * Return float
+ * This method get the element radius
+ */
+ function get_radius_element(element) {
+ var size = get_size_element(element);
+
+ return Math.sqrt(Math.pow(size[0] / 2, 2) + Math.pow(size[1] / 2, 2));
+ }
+
+ /**
+ * Function get_scale_element
+ * Return float
+ * This method get the element escale
+ */
+ function get_scale_element(element) {
+ var element_t = d3.transform(d3.select(element).attr("transform"));
+ var element_t_scale = parseFloat(element_t["scale"]);
+
+ return element_t_scale;
+ }
+
+ /**
+ * Function get_size_element
+ * Return array[2]
+ * This method get the element size [width, height]
+ */
+ function get_size_element(element) {
+ var element_b = d3
+ .select(element)
+ .node()
+ .getBBox();
+
+ return [element_b["width"], element_b["height"]];
+ }
+
+ /**
+ * Function get_pos_element
+ * Return array[2]
+ * This method get the element position [x, y]
+ */
+ function get_pos_element(element) {
+ var element_t = d3.transform(d3.select(element).attr("transform"));
+ var element_t_scale = parseFloat(element_t["scale"]);
+ var element_b = d3
+ .select(element)
+ .node()
+ .getBBox();
+
+ var box_x =
+ parseFloat(element_t.translate[0]) +
+ parseFloat(element_b["x"]) * element_t_scale;
+ var box_y =
+ parseFloat(element_t.translate[1]) +
+ parseFloat(element_b["y"]) * element_t_scale;
+
+ return [box_x, box_y];
+ }
+
+ /**
+ * Function get_center_element
+ * Return array[2]
+ * This method ge2t the element center point [x, y]
+ */
+ function get_center_element(element) {
+ var element_t = d3.transform(d3.select(element).attr("transform"));
+ var element_t_scale = parseFloat(element_t["scale"]);
+ var element_b = d3
+ .select(element)
+ .node()
+ .getBBox();
+
+ var box_x =
+ parseFloat(element_t.translate[0]) +
+ parseFloat(element_b["x"]) * element_t_scale;
+ var box_y =
+ parseFloat(element_t.translate[1]) +
+ parseFloat(element_b["y"]) * element_t_scale;
+
+ var width = element_t_scale * element_b["width"];
+ var height = element_t_scale * element_b["height"];
+
+ var c_x = box_x + width / 2;
+ var c_y = box_y + height / 2;
+
+ return [c_x, c_y];
+ }
+
+ /**
+ * Function get_distance_between_point
+ * Return float
+ * This method get the distance betweeen two points
+ */
+ function get_distance_between_point(point1, point2) {
+ delta_x = Math.abs(point1[0] - point2[0]);
+ delta_y = Math.abs(point1[1] - point1[1]);
+
+ return Math.sqrt(Math.pow(delta_x, 2) + Math.pow(delta_y, 2));
+ }
+
+ /**
+ * Function get_angle_of_line
+ * Return float
+ * This method get the angle of line and x axe
+ */
+ function get_angle_of_line(point1, point2) {
+ return (
+ (Math.atan2(point2[1] - point1[1], point2[0] - point1[0]) * 180) /
+ Math.PI
+ );
+ }
+
+ function arrow_by_pieces2(id_arrow, element1, element2, step) {
+ if (typeof step === "undefined") step = 0;
+
+ step++;
+
+ switch (step) {
+ case 1:
+ wait_for_preload_symbols(
+ ["body_arrow.svg#body_arrow", "head_arrow.svg#head_arrow"],
+ function() {
+ arrow_by_pieces2(id_arrow, element1, element2, step);
+ }
+ );
+ break;
+ case 2:
+ var arrow = svg
+ .append("g")
+ .attr("id", id_arrow)
+ .attr("style", "opacity: 0");
+
+ arrow
+ .append("g")
+ .attr("id", "body")
+ .append("use")
+ .attr("xlink:href", "body_arrow.svg#body_arrow");
+
+ arrow
+ .append("g")
+ .attr("id", "head")
+ .append("use")
+ .attr("xlink:href", "head_arrow.svg#head_arrow");
+
+ var c_elem1 = get_center_element("#" + element1);
+ var c_elem2 = get_center_element("#" + element2);
+ var distance = get_distance_between_point(c_elem1, c_elem2);
+
+ var transform = d3.transform();
+
+ /*---------------------------------------------*/
+ /*--- Position of layer arrow (body + head) ---*/
+ /*---------------------------------------------*/
+ var arrow = d3.select("#" + id_arrow);
+
+ var arrow_body = d3.select("#" + id_arrow + " #body");
+ var arrow_body_b = arrow_body.node().getBBox();
+
+ transform.translate[0] = c_elem1[0];
+ transform.translate[1] = c_elem1[1] - arrow_body_b["height"] / 2;
+ transform.rotate = get_angle_of_line(c_elem1, c_elem2);
+
+ arrow.attr("transform", transform.toString());
+
+ /*---------------------------------------------*/
+ /*-------- Resize the body arrow width --------*/
+ /*---------------------------------------------*/
+ var arrow_body = d3.select("#" + id_arrow + " #body");
+ var arrow_body_b = arrow_body.node().getBBox();
+ var arrow_head = d3.select("#" + id_arrow + " #head");
+ var arrow_head_b = arrow_head.node().getBBox();
+
+ var body_width = distance - arrow_head_b["width"];
+
+ transform = d3.transform();
+ transform.scale[0] = body_width / arrow_body_b["width"];
+ arrow_body.attr("transform", transform.toString());
+
+ /*---------------------------------------------*/
+ /*---------- Position of head arrow -----------*/
+ /*---------------------------------------------*/
+ transform = d3.transform();
+
+ var arrow_body_t = d3.transform(arrow_body.attr("transform"));
+
+ var scale = arrow_body_t.scale[0];
+ var x = 0 + arrow_body_b["width"] * scale;
+ var y =
+ 0 + (arrow_body_b["height"] / 2 - arrow_head_b["height"] / 2);
+
+ transform.translate[0] = x;
+ transform.translate[1] = y;
+
+ arrow_head.attr("transform", transform.toString());
+
+ /*---------------------------------------------*/
+ /*------- Show the result in one time ---------*/
+ /*---------------------------------------------*/
+ arrow.attr("style", "opacity: 1");
+ break;
+ }
+ }
+
+ function wait_for_preload_symbols(symbols, callback) {
+ var count_symbols = symbols.length;
+
+ function wait(symbol, callback) {
+ switch (is_preload_symbol(symbol)) {
+ case -1:
+ preload_symbol(symbol);
+
+ setTimeout(function() {
+ wait(symbol, callback);
+ }, 100);
+ break;
+ case 0:
+ // Wait
+ setTimeout(function() {
+ wait(symbol, callback);
+ }, 100);
+ break;
+ case 1:
+ count_symbols--;
+ break;
+ }
+
+ if (count_symbols == 0) {
+ //~ setTimeout(function() {
+ //~ callback();
+ //~ }, 1000);
+ callback();
+ }
+ }
+
+ for (var i in symbols) {
+ wait(symbols[i], callback);
+ }
+ }
+
+ function preload_symbol(symbol, param_step) {
+ var step;
+
+ if (typeof param_step == "undefined") {
+ step = 1;
+ param_step = 1;
+ } else {
+ step = param_step;
+ }
+
+ step++;
+
+ var base64symbol = btoa(symbol).replace(/=/g, "");
+
+ var callback = function(e) {
+ preload_symbol(symbol, step);
+ };
+
+ switch (param_step) {
+ case 1:
+ d3.select("svg")
+ .append("g")
+ .attr("id", base64symbol)
+ .attr("data-loaded", 0)
+ .style("opacity", 0)
+ .append("use")
+ .attr("xlink:href", symbol)
+ .on("load", callback);
+ break;
+ case 2:
+ d3.select("#" + base64symbol).attr("data-loaded", 1);
+
+ break;
+ }
+ }
+
+ function is_preload_symbol(symbol) {
+ var base64symbol = btoa(symbol).replace(/=/g, "");
+
+ if (d3.select("#" + base64symbol).node() === null) return -1;
+
+ return parseInt(d3.select("#" + base64symbol).attr("data-loaded"));
+ }
+
+