]> arthur.barton.de Git - netdata.git/blobdiff - web/index.html
updated copyright dates
[netdata.git] / web / index.html
index 9cf7eb291dcac97323bebd55c54febffab2563ce..d8e1282344daca504ae02de53fc4991bfa4988d2 100644 (file)
 
     <link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACNklEQVRYhcXXv2tUQRAH8M+FEIJISBHCIWIhIQSUILERi4AiiqCggiIiomAjlhaC4j+ghYWISgqNohZaCBZBC8Ei8QdEUCutFBsxCBqDYkgci/cunkfuJffjJQPD8mZm5/vd2WV2HzlJ0Bs8CvrywsgCHwy+BpGOg0sJfjj4nYKX9FdwKG9gwZlgtgK8pLOpPxfw1mCoCnClDgWtzQTvCEYWCV7SkWAlFBoEb8dlDKBF8t2bMWUSH/AHr3CiEfz5CPUusPJLkRCdk5ZqyeqUrQv4R7E5TwK7M3zTeIKduRAIitiWEfIY69GdCwGcRFuG/xqONRkzkaA7+J5x+MaDtWmHvJ4HgeEM8Nn0bridfv9HoOFyBAdwJCPkqqTzHWwUaz7wgeBHxupfBKuCj2W25mxBsCGYyAB/FxTT27HcPlyep64tCLbjKbqqhLzBlgKfF8pVE4FgRXABI+ioEnYfOyzcFWsCbg+OV+xlpU4ER4O+4HVwL51b3xYEXcGu4Ao+YQhr5gmdxHmsQyfG0b/YxbWmLfRWmnxa0s06VbTMCpnBS9zFzQKTwR5cXCzwHIE02Sl8wSZsRI/kgLVJqjSd+t9LVjiG1diPszhdK3A5gR48k5zYMTwscC59sfT799CYKvA8EttbSeXgTr3gJQKl91kR+yTlvyG5uUbLYh9gb+ovltkb6qYtNSRo3kOygsBSzGlKsubf43USWLYK5CLLXoFWyU/CtzLbVDpW2n+m40yN9ukqdvAX9ac/EIgOapcAAAAASUVORK5CYII=">
 
-    <meta property="og:locale" content="en_US" />
-    <meta property="og:image" content="https://cloud.githubusercontent.com/assets/2662304/19168687/f6a567be-8c19-11e6-8561-ce8d589e8346.gif"/>
-    <meta property="og:url" content="http://my-netdata.io/"/>
-    <meta property="og:type" content="website"/>
-    <meta property="og:site_name" content="netdata"/>
-    <meta property="og:title" content="netdata - real-time performance monitoring, done right!"/>
-    <meta property="og:description" content="Stunning real-time dashboards, blazingly fast and extremely interactive. Zero configuration, zero dependencies, zero maintenance." />
+    <meta property="og:locale"             content="en_US" />
+    <meta property="og:url"                content="https://my-netdata.io" />
+    <meta property="og:type"               content="website" />
+    <meta property="og:site_name"          content="netdata"/>
+    <meta property="og:title"              content="Get control of your Linux Servers. Simple. Effective. Awesome." />
+    <meta property="og:description"        content="Unparalleled insights, in real-time, of everything happening on your Linux systems and applications, with stunning, interactive web dashboards and powerful performance and health alarms." />
+    <meta property="og:image"              content="https://cloud.githubusercontent.com/assets/2662304/20910305/65d10354-bb69-11e6-8128-c44b547517b4.png" />
+    <meta property="og:image:type"         content="image/png" />
+    <meta property="fb:app_id"             content="1200089276712916" />
+
+    <meta name="twitter:card"              content="summary" />
+    <meta name="twitter:site"              content="@linuxnetdata" />
+    <meta name="twitter:title"             content="Get control of your Linux Servers. Simple. Effective. Awesome." />
+    <meta name="twitter:description"       content="Unparalleled insights, in real-time, of everything happening on your Linux systems and applications, with stunning, interactive web dashboards and powerful performance and health alarms." />
+    <meta name="twitter:image"             content="https://cloud.githubusercontent.com/assets/2662304/14092712/93b039ea-f551-11e5-822c-beadbf2b2a2e.gif" />
 
     <style>
     /* prevent body from hiding under the navbar */
         font-weight: 500;
         color: #767676;
     }
+    .dashboard-sidebar .nav > li > a > .fa {
+        width: 20px;
+        text-align: center;
+    }
     .dashboard-sidebar .nav > li > a:hover,
     .dashboard-sidebar .nav > li > a:focus {
         padding-left: 19px;
     }
 
     </style>
-</head>
 
-<!-- check which theme to use -->
-<script type="text/javascript">
-    // enable alarms checking and notifications
-    var netdataShowAlarms = true;
-
-    // enable registry updates
-    var netdataRegistry = true;
-
-    // --------------------------------------------------------------------
-    // urlOptions
-
-    var urlOptions = {
-        hash: '#',
-        theme: null,
-        help: null,
-        update_always: false,
-        pan_and_zoom: false,
-        after: 0,
-        before: 0,
-        nowelcome: false,
-        show_alarms: false,
-        chart: null,
-        family: null,
-        alarm: null,
-        alarm_unique_id: 0,
-        alarm_id: 0,
-        alarm_event_id: 0,
-
-        hasProperty: function(property) {
-            // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
-            return typeof this[property] !== 'undefined';
-        },
-
-        genHash: function() {
-            var hash = urlOptions.hash;
-
-            if(urlOptions.pan_and_zoom === true) {
-                hash += ';after='  + urlOptions.after.toString() +
-                        ';before=' + urlOptions.before.toString();
-            }
+    <!-- check which theme to use -->
+    <script type="text/javascript">
+        // enable alarms checking and notifications
+        var netdataShowAlarms = true;
+
+        // enable registry updates
+        var netdataRegistry = true;
+
+        // --------------------------------------------------------------------
+        // urlOptions
+
+        var urlOptions = {
+            hash: '#',
+            theme: null,
+            help: null,
+            update_always: false,
+            pan_and_zoom: false,
+            after: 0,
+            before: 0,
+            nowelcome: false,
+            show_alarms: false,
+            chart: null,
+            family: null,
+            alarm: null,
+            alarm_unique_id: 0,
+            alarm_id: 0,
+            alarm_event_id: 0,
+
+            hasProperty: function(property) {
+                // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
+                return typeof this[property] !== 'undefined';
+            },
+
+            genHash: function() {
+                var hash = urlOptions.hash;
+
+                if(urlOptions.pan_and_zoom === true) {
+                    hash += ';after='  + urlOptions.after.toString() +
+                            ';before=' + urlOptions.before.toString();
+                }
 
-            if(urlOptions.theme !== null)
-                hash += ';theme=' + urlOptions.theme.toString();
+                if(urlOptions.theme !== null)
+                    hash += ';theme=' + urlOptions.theme.toString();
 
-            if(urlOptions.help !== null)
-                hash += ';help=' + urlOptions.help.toString();
+                if(urlOptions.help !== null)
+                    hash += ';help=' + urlOptions.help.toString();
 
-            if(urlOptions.update_always === true)
-                hash += ';update_always=true';
+                if(urlOptions.update_always === true)
+                    hash += ';update_always=true';
 
-            return hash;
-        },
+                return hash;
+            },
 
-        parseHash: function() {
-            var variables = document.location.hash.split(';');
-            var len = variables.length;
-            while(len--) {
-                if(len !== 0) {
-                    var p = variables[len].split('=');
-                    if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
-                        urlOptions[p[0]] = decodeURIComponent(p[1]);
+            parseHash: function() {
+                var variables = document.location.hash.split(';');
+                var len = variables.length;
+                while(len--) {
+                    if(len !== 0) {
+                        var p = variables[len].split('=');
+                        if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
+                            urlOptions[p[0]] = decodeURIComponent(p[1]);
+                    }
+                    else {
+                        if(variables[len].length > 0)
+                            urlOptions.hash = variables[len];
+                    }
                 }
-                else {
-                    if(variables[len].length > 0)
-                        urlOptions.hash = variables[len];
+
+                var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom', 'update_always' ];
+                len = booleans.length;
+                while(len--) {
+                    if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1)
+                        urlOptions[booleans[len]] = true;
+                    else
+                        urlOptions[booleans[len]] = false;
                 }
-            }
 
-            var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom', 'update_always' ];
-            len = booleans.length;
-            while(len--) {
-                if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1)
-                    urlOptions[booleans[len]] = true;
+                if(urlOptions.before > 0 && urlOptions.after > 0) {
+                    urlOptions.pan_and_zoom = true;
+                    urlOptions.nowelcome = true;
+                }
                 else
-                    urlOptions[booleans[len]] = false;
-            }
+                    urlOptions.pan_and_zoom = false;
+
+                // console.log(urlOptions);
+            },
+
+            hashUpdate: function() {
+                history.replaceState(null, '', urlOptions.genHash());
+            },
 
-            if(urlOptions.before > 0 && urlOptions.after > 0) {
-                urlOptions.pan_and_zoom = true;
-                urlOptions.nowelcome = true;
+            netdataPanAndZoomCallback: function(status, after, before) {
+                urlOptions.pan_and_zoom = status;
+                urlOptions.after = after;
+                urlOptions.before = before;
+                urlOptions.hashUpdate();
             }
-            else
-                urlOptions.pan_and_zoom = false;
 
-            // console.log(urlOptions);
-        },
+        };
 
-        hashUpdate: function() {
-            history.replaceState(null, '', urlOptions.genHash());
-        },
+        urlOptions.parseHash();
 
-        netdataPanAndZoomCallback: function(status, after, before) {
-            urlOptions.pan_and_zoom = status;
-            urlOptions.after = after;
-            urlOptions.before = before;
-            urlOptions.hashUpdate();
-        }
+        // --------------------------------------------------------------------
+        // check options that should be processed before loading netdata.js
 
-    };
+        function loadLocalStorage(name) {
+            var ret = null;
 
-    urlOptions.parseHash();
+            try {
+                if(typeof Storage !== "undefined" && typeof localStorage === 'object')
+                    ret = localStorage.getItem(name);
+            }
+            catch(error) {
+                ;
+            }
 
-    // --------------------------------------------------------------------
-    // check options that should be processed before loading netdata.js
+            if(typeof ret === 'undefined' || ret === null)
+                return null;
 
-    function loadLocalStorage(name) {
-        var ret = null;
+            // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
 
-        try {
-            if(typeof Storage !== "undefined" && typeof localStorage === 'object')
-                ret = localStorage.getItem(name);
-        }
-        catch(error) {
-            ;
+            return ret;
         }
 
-        if(typeof ret === 'undefined' || ret === null)
-            return null;
-
-        // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
+        function saveLocalStorage(name, value) {
+            // console.log('saving: ' + name.toString() + ' = ' + value.toString());
+            try {
+                if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
+                    localStorage.setItem(name, value.toString());
+                    return true;
+                }
+            }
+            catch(error) {
+                ;
+            }
 
-        return ret;
-    }
+            return false;
+        }
 
-    function saveLocalStorage(name, value) {
-        // console.log('saving: ' + name.toString() + ' = ' + value.toString());
-        try {
-            if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
-                localStorage.setItem(name, value.toString());
-                return true;
-            }
+        function getTheme(def) {
+            var ret = loadLocalStorage('netdataTheme');
+            if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
+                return def;
+            else
+                return ret;
         }
-        catch(error) {
-            ;
+
+        function setTheme(theme) {
+            if(theme === netdataTheme) return false;
+            return saveLocalStorage('netdataTheme', theme);
         }
 
-        return false;
-    }
+        var netdataTheme = getTheme('slate');
+        var netdataShowHelp = true;
 
-    function getTheme(def) {
-        var ret = loadLocalStorage('netdataTheme');
-        if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
-            return def;
+        if(urlOptions.theme !== null) {
+            setTheme(urlOptions.theme);
+            netdataTheme = urlOptions.theme;
+        }
         else
-            return ret;
-    }
+            urlOptions.theme = netdataTheme;
 
-    function setTheme(theme) {
-        if(theme === netdataTheme) return false;
-        return saveLocalStorage('netdataTheme', theme);
-    }
-
-    var netdataTheme = getTheme('slate');
-    var netdataShowHelp = true;
-
-    if(urlOptions.theme !== null) {
-        setTheme(urlOptions.theme);
-        netdataTheme = urlOptions.theme;
-    }
-    else
-        urlOptions.theme = netdataTheme;
-
-    if(urlOptions.help !== null) {
-        saveLocalStorage('options.show_help', urlOptions.help);
-        netdataShowHelp = urlOptions.help;
-    }
-    else {
-        urlOptions.help = loadLocalStorage('options.show_help');
-    }
+        if(urlOptions.help !== null) {
+            saveLocalStorage('options.show_help', urlOptions.help);
+            netdataShowHelp = urlOptions.help;
+        }
+        else {
+            urlOptions.help = loadLocalStorage('options.show_help');
+        }
 
-    // --------------------------------------------------------------------
-    // registry call back to render my-netdata menu
+        // --------------------------------------------------------------------
+        // registry call back to render my-netdata menu
 
-    var netdataRegistryCallback = function(machines_array) {
-        var el = '';
-        var a1 = '';
-        var found = 0;
+        var netdataRegistryCallback = function(machines_array) {
+            var el = '';
+            var a1 = '';
+            var found = 0;
 
-        if(machines_array === null) {
-            var ret = loadLocalStorage("registryCallback");
-            if(typeof ret !== 'undefined' && ret !== null) {
-                machines_array = JSON.parse(ret);
-                console.log("failed to contact the registry - loaded registry data from browser local storage");
+            if(machines_array === null) {
+                var ret = loadLocalStorage("registryCallback");
+                if(typeof ret !== 'undefined' && ret !== null) {
+                    machines_array = JSON.parse(ret);
+                    console.log("failed to contact the registry - loaded registry data from browser local storage");
+                }
             }
-        }
 
-        if(machines_array) {
-            saveLocalStorage("registryCallback", JSON.stringify(machines_array));
+            if(machines_array) {
+                saveLocalStorage("registryCallback", JSON.stringify(machines_array));
 
-            var machines = machines_array.sort(function (a, b) {
-                if (a.name > b.name) return -1;
-                if (a.name < b.name) return 1;
-                return 0;
-            });
+                var machines = machines_array.sort(function (a, b) {
+                    if (a.name > b.name) return -1;
+                    if (a.name < b.name) return 1;
+                    return 0;
+                });
 
-            var len = machines.length;
-            while(len--) {
-                var u = machines[len];
-                found++;
-                el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
-                a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
+                var len = machines.length;
+                while(len--) {
+                    var u = machines[len];
+                    found++;
+                    el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
+                    a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
+                }
             }
-        }
 
-        if(!found) {
-            if(machines)
-                el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">your netdata server list is empty...</a></li>';
-            else
-                el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">failed to contact the registry...</a></li>';
-
-            a1 += '<li><a href="#" onClick="return false;">&nbsp;</a></li>';
-
-            el += '<li role="separator" class="divider"></li>' +
-                    '<li><a href="//london.netdata.rocks/default.html">UK - London (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//newyork.netdata.rocks/default.html">US - New York (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//sanfrancisco.netdata.rocks/default.html">US - San Francisco (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
-                    '<li><a href="//frankfurt.netdata.rocks/default.html">Germany - Frankfurt (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//toronto.netdata.rocks/default.html">Canada - Toronto (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//singapore.netdata.rocks/default.html">Japan - Singapore (DigitalOcean.com)</a></li>' +
-                    '<li><a href="//bangalore.netdata.rocks/default.html">India - Bangalore (DigitalOcean.com)</a></li>';
-            a1 += '<li role="separator" class="divider"></li>' +
-                    '<li><a href="#">&nbsp;</a></li>' +
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>'+
-                    '<li><a href="#">&nbsp;</a></li>';
-        }
-
-        el += '<li role="separator" class="divider"></li>';
-        a1 += '<li role="separator" class="divider"></li>';
+            if(!found) {
+                if(machines)
+                    el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">your netdata server list is empty...</a></li>';
+                else
+                    el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">failed to contact the registry...</a></li>';
+
+                a1 += '<li><a href="#" onClick="return false;">&nbsp;</a></li>';
+
+                el += '<li role="separator" class="divider"></li>' +
+                        '<li><a href="//london.netdata.rocks/default.html">UK - London (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//newyork.netdata.rocks/default.html">US - New York (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//sanfrancisco.netdata.rocks/default.html">US - San Francisco (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
+                        '<li><a href="//frankfurt.netdata.rocks/default.html">Germany - Frankfurt (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//toronto.netdata.rocks/default.html">Canada - Toronto (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//singapore.netdata.rocks/default.html">Japan - Singapore (DigitalOcean.com)</a></li>' +
+                        '<li><a href="//bangalore.netdata.rocks/default.html">India - Bangalore (DigitalOcean.com)</a></li>';
+                a1 += '<li role="separator" class="divider"></li>' +
+                        '<li><a href="#">&nbsp;</a></li>' +
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>'+
+                        '<li><a href="#">&nbsp;</a></li>';
+            }
 
-        el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
-        a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>'
+            el += '<li role="separator" class="divider"></li>';
+            a1 += '<li role="separator" class="divider"></li>';
 
-        document.getElementById('mynetdata_servers').innerHTML = el;
-        document.getElementById('mynetdata_servers2').innerHTML = el;
-        document.getElementById('mynetdata_actions1').innerHTML = a1;
+            el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
+            a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>'
 
-        gotoServerInit();
-    };
+            document.getElementById('mynetdata_servers').innerHTML = el;
+            document.getElementById('mynetdata_servers2').innerHTML = el;
+            document.getElementById('mynetdata_actions1').innerHTML = a1;
 
-    var this_is_demo = null; // FIXME
-    function isdemo() {
-        if(this_is_demo !== null) return this_is_demo;
-        this_is_demo = false;
+            gotoServerInit();
+        };
 
-        try {
-            if(typeof document.location.hostname === 'string') {
-                if(document.location.hostname.endsWith('.my-netdata.io') ||
-                        document.location.hostname.endsWith('.mynetdata.io') ||
-                        document.location.hostname.endsWith('.netdata.rocks') ||
-                        document.location.hostname.endsWith('.firehol.org') ||
-                        document.location.hostname.endsWith('.netdata.online'))
-                        this_is_demo = true;
+        var this_is_demo = null; // FIXME
+        function isdemo() {
+            if(this_is_demo !== null) return this_is_demo;
+            this_is_demo = false;
+
+            try {
+                if(typeof document.location.hostname === 'string') {
+                    if(document.location.hostname.endsWith('.my-netdata.io') ||
+                            document.location.hostname.endsWith('.mynetdata.io') ||
+                            document.location.hostname.endsWith('.netdata.rocks') ||
+                            document.location.hostname.endsWith('.firehol.org') ||
+                            document.location.hostname.endsWith('.netdata.online'))
+                            this_is_demo = true;
+                }
+            }
+            catch(error) {
+                ;
             }
-        }
-        catch(error) {
-            ;
-        }
 
-        return this_is_demo;
-    }
+            return this_is_demo;
+        }
 
-    function netdataURL(url) {
-        if(typeof url === 'undefined')
-            url = document.location.toString();
+        function netdataURL(url) {
+            if(typeof url === 'undefined')
+                url = document.location.toString();
 
-        if(url.indexOf('#') !== -1)
-            url = url.substring(0, url.indexOf('#'));
+            if(url.indexOf('#') !== -1)
+                url = url.substring(0, url.indexOf('#'));
 
-        var hash = urlOptions.genHash();
+            var hash = urlOptions.genHash();
 
-        // console.log('netdataURL: ' + url + hash);
+            // console.log('netdataURL: ' + url + hash);
 
-        return url + hash;
-    }
+            return url + hash;
+        }
 
-    function netdataReload(url) {
-        var t = netdataURL(url);
-        // console.log('netdataReload: ' + t);
-        document.location = t;
+        function netdataReload(url) {
+            var t = netdataURL(url);
+            // console.log('netdataReload: ' + t);
+            document.location = t;
 
-        // since we play with hash
-        // this is needed to reload the page
-        location.reload();
-    }
+            // since we play with hash
+            // this is needed to reload the page
+            location.reload();
+        }
 
-    var gotoServerValidateRemaining = 0;
-    var gotoServerMiddleClick = false;
-    var gotoServerStop = false;
-    function gotoServerValidateUrl(id, guid, url) {
-        var penaldy = 0;
-        var error = 'failed';
+        var gotoServerValidateRemaining = 0;
+        var gotoServerMiddleClick = false;
+        var gotoServerStop = false;
+        function gotoServerValidateUrl(id, guid, url) {
+            var penaldy = 0;
+            var error = 'failed';
 
-        if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
-            // we penalize https only if the current url is http
-            // to allow the user walk through all its servers.
-            penaldy = 500;
+            if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
+                // we penalize https only if the current url is http
+                // to allow the user walk through all its servers.
+                penaldy = 500;
 
-        else if(document.location.toString().startsWith('https://') && url.toString().startsWith('http://'))
-            error = 'can\'t check';
+            else if(document.location.toString().startsWith('https://') && url.toString().startsWith('http://'))
+                error = 'can\'t check';
 
-        var finalURL = netdataURL(url);
+            var finalURL = netdataURL(url);
 
-        setTimeout(function() {
-            document.getElementById('gotoServerList').innerHTML += '<tr><td style="padding-left: 20px;"><a href="' + finalURL + '" target="_blank">' + url + '</a></td><td style="padding-left: 30px;"><code id="' + guid + '-' + id + '-status">checking...</code></td></tr>';
+            setTimeout(function() {
+                document.getElementById('gotoServerList').innerHTML += '<tr><td style="padding-left: 20px;"><a href="' + finalURL + '" target="_blank">' + url + '</a></td><td style="padding-left: 30px;"><code id="' + guid + '-' + id + '-status">checking...</code></td></tr>';
 
-            NETDATA.registry.hello(url, function(data) {
-                if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid === guid) {
-                    // console.log('OK ' + id + ' URL: ' + url);
-                    document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
+                NETDATA.registry.hello(url, function(data) {
+                    if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid === guid) {
+                        // console.log('OK ' + id + ' URL: ' + url);
+                        document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
 
-                    if(!gotoServerStop) {
-                        gotoServerStop = true;
+                        if(!gotoServerStop) {
+                            gotoServerStop = true;
 
-                        if(gotoServerMiddleClick) {
-                            window.open(finalURL, '_blank');
-                            gotoServerMiddleClick = false;
-                            document.getElementById('gotoServerResponse').innerHTML = '<b>Opening new window to ' + NETDATA.registry.machines[guid].name + '<br/><a href="' + finalURL + '">' + url + '</a></b><br/>(check your pop-up blocker if it fails)';
-                        }
-                        else {
-                            document.getElementById('gotoServerResponse').innerHTML += 'found it! It is at:<br/><small>' + url + '</small>';
-                            document.location = finalURL;
+                            if(gotoServerMiddleClick) {
+                                window.open(finalURL, '_blank');
+                                gotoServerMiddleClick = false;
+                                document.getElementById('gotoServerResponse').innerHTML = '<b>Opening new window to ' + NETDATA.registry.machines[guid].name + '<br/><a href="' + finalURL + '">' + url + '</a></b><br/>(check your pop-up blocker if it fails)';
+                            }
+                            else {
+                                document.getElementById('gotoServerResponse').innerHTML += 'found it! It is at:<br/><small>' + url + '</small>';
+                                document.location = finalURL;
+                            }
                         }
                     }
-                }
-                else {
-                    if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid !== guid)
-                        error = 'wrong machine';
-
-                    document.getElementById(guid + '-' + id + '-status').innerHTML = error;
-                    gotoServerValidateRemaining--;
-                    if(gotoServerValidateRemaining <= 0) {
-                        gotoServerMiddleClick = false;
-                        document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
-                    }
-                }
-            });
-        }, (id * 50) + penaldy);
-    }
-
-    function gotoServerModalHandler(guid) {
-        // console.log('goto server: ' + guid);
-
-        gotoServerStop = false;
-        var checked = {};
-        var len = NETDATA.registry.machines[guid].alternate_urls.length;
-        var count = 0;
-
-        document.getElementById('gotoServerResponse').innerHTML = '';
-        document.getElementById('gotoServerList').innerHTML = '';
-        document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
-        $('#gotoServerModal').modal('show');
-
-        gotoServerValidateRemaining = len;
-        while(len--) {
-            var url = NETDATA.registry.machines[guid].alternate_urls[len];
-            checked[url] = true;
-            gotoServerValidateUrl(count++, guid, url);
-        }
+                    else {
+                        if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid !== guid)
+                            error = 'wrong machine';
 
-        setTimeout(function() {
-            if(gotoServerStop === false) {
-                document.getElementById('gotoServerResponse').innerHTML = '<b>Added all the known URLs for this machine.</b>';
-                NETDATA.registry.search(guid, function(data) {
-                    // console.log(data);
-                    len = data.urls.length;
-                    while(len--) {
-                        var url = data.urls[len][1];
-                        // console.log(url);
-                        if(typeof checked[url] === 'undefined') {
-                            gotoServerValidateRemaining++;
-                            checked[url] = true;
-                            gotoServerValidateUrl(count++, guid, url);
+                        document.getElementById(guid + '-' + id + '-status').innerHTML = error;
+                        gotoServerValidateRemaining--;
+                        if(gotoServerValidateRemaining <= 0) {
+                            gotoServerMiddleClick = false;
+                            document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
                         }
                     }
                 });
-            }
-        }, 2000);
-        return false;
-    }
+            }, (id * 50) + penaldy);
+        }
 
-    function gotoServerInit() {
-        $(".registry_link").on('click', function(e) {
-            if(e.which === 2) {
-                e.preventDefault();
-                gotoServerMiddleClick = true;
-            }
-            else {
-                gotoServerMiddleClick = false;
-            }
+        function gotoServerModalHandler(guid) {
+            // console.log('goto server: ' + guid);
 
-            return true;
-        });
-    }
+            gotoServerStop = false;
+            var checked = {};
+            var len = NETDATA.registry.machines[guid].alternate_urls.length;
+            var count = 0;
 
-    function switchRegistryModalHandler() {
-        document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
-        document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
-        document.getElementById('switchRegistryResponse').innerHTML = '';
-        $('#switchRegistryModal').modal('show');
-    }
+            document.getElementById('gotoServerResponse').innerHTML = '';
+            document.getElementById('gotoServerList').innerHTML = '';
+            document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
+            $('#gotoServerModal').modal('show');
 
-    function notifyForSwitchRegistry() {
-        var n = document.getElementById('switchRegistryPersonGUID').value;
+            gotoServerValidateRemaining = len;
+            while(len--) {
+                var url = NETDATA.registry.machines[guid].alternate_urls[len];
+                checked[url] = true;
+                gotoServerValidateUrl(count++, guid, url);
+            }
 
-        if(n !== '' && n.length === 36) {
-            NETDATA.registry.switch(n, function(result) {
-                if(result !== null) {
-                    $('#switchRegistryModal').modal('hide');
-                    NETDATA.registry.init();
-                }
-                else {
-                    document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
+            setTimeout(function() {
+                if(gotoServerStop === false) {
+                    document.getElementById('gotoServerResponse').innerHTML = '<b>Added all the known URLs for this machine.</b>';
+                    NETDATA.registry.search(guid, function(data) {
+                        // console.log(data);
+                        len = data.urls.length;
+                        while(len--) {
+                            var url = data.urls[len][1];
+                            // console.log(url);
+                            if(typeof checked[url] === 'undefined') {
+                                gotoServerValidateRemaining++;
+                                checked[url] = true;
+                                gotoServerValidateUrl(count++, guid, url);
+                            }
+                        }
+                    });
                 }
-            });
+            }, 2000);
+            return false;
         }
-        else
-            document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
-    }
-
-    var deleteRegistryUrl = null;
-    function deleteRegistryModalHandler(guid, name, url) {
-        deleteRegistryUrl = url;
-        document.getElementById('deleteRegistryServerName').innerHTML = name;
-        document.getElementById('deleteRegistryServerName2').innerHTML = name;
-        document.getElementById('deleteRegistryServerURL').innerHTML = url;
-        document.getElementById('deleteRegistryResponse').innerHTML = '';
-        $('#deleteRegistryModal').modal('show');
-    }
 
-    function notifyForDeleteRegistry() {
-        if(deleteRegistryUrl) {
-            NETDATA.registry.delete(deleteRegistryUrl, function(result) {
-                if(result !== null) {
-                    deleteRegistryUrl = null;
-                    $('#deleteRegistryModal').modal('hide');
-                    NETDATA.registry.init();
+        function gotoServerInit() {
+            $(".registry_link").on('click', function(e) {
+                if(e.which === 2) {
+                    e.preventDefault();
+                    gotoServerMiddleClick = true;
                 }
                 else {
-                    document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
+                    gotoServerMiddleClick = false;
                 }
+
+                return true;
             });
         }
-    }
 
-    var options = {
-        sparklines_registry: {},
-        menus: {},
-        submenu_names: {},
-        data: null,
-        hostname: 'netdata_server', // will be overwritten by the netdata server
-        categories: new Array(),
-        categories_idx: {},
-        families: new Array(),
-        families_idx: {},
-
-        chartsPerRow: 0,
-        chartsMinWidth: 1450,
-        chartsHeight: 180,
-        sparklinesHeight: 60,
-    };
-
-    // generate a sparkline
-    // used in the documentation
-    function sparkline(chart, dimension, units) {
-        var key = chart + '.' + dimension;
-
-        if(typeof units === 'undefined')
-            units = '';
-
-        if(typeof options.sparklines_registry[key] === 'undefined')
-            options.sparklines_registry[key] = { count: 1 };
-        else
-            options.sparklines_registry[key].count++;
+        function switchRegistryModalHandler() {
+            document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
+            document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
+            document.getElementById('switchRegistryResponse').innerHTML = '';
+            $('#switchRegistryModal').modal('show');
+        }
 
-        key = key + '.' + options.sparklines_registry[key].count;
+        function notifyForSwitchRegistry() {
+            var n = document.getElementById('switchRegistryPersonGUID').value;
 
-        var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
+            if(n !== '' && n.length === 36) {
+                NETDATA.registry.switch(n, function(result) {
+                    if(result !== null) {
+                        $('#switchRegistryModal').modal('hide');
+                        NETDATA.registry.init();
+                    }
+                    else {
+                        document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
+                    }
+                });
+            }
+            else
+                document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
+        }
 
-        return h;
-    }
+        var deleteRegistryUrl = null;
+        function deleteRegistryModalHandler(guid, name, url) {
+            deleteRegistryUrl = url;
+            document.getElementById('deleteRegistryServerName').innerHTML = name;
+            document.getElementById('deleteRegistryServerName2').innerHTML = name;
+            document.getElementById('deleteRegistryServerURL').innerHTML = url;
+            document.getElementById('deleteRegistryResponse').innerHTML = '';
+            $('#deleteRegistryModal').modal('show');
+        }
 
-    function chartsPerRow(total) {
-        if(options.chartsPerRow === 0) {
-            width = Math.floor(total / options.chartsMinWidth);
-            if(width === 0) width = 1;
-            return width;
+        function notifyForDeleteRegistry() {
+            if(deleteRegistryUrl) {
+                NETDATA.registry.delete(deleteRegistryUrl, function(result) {
+                    if(result !== null) {
+                        deleteRegistryUrl = null;
+                        $('#deleteRegistryModal').modal('hide');
+                        NETDATA.registry.init();
+                    }
+                    else {
+                        document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
+                    }
+                });
+            }
         }
-        else return options.chartsPerRow;
-    }
 
-    function prioritySort(a, b) {
-        if(a.priority < b.priority) return -1;
-        if(a.priority > b.priority) return 1;
-        if(a.name < b.name) return -1;
-        return 1;
-    }
+        var options = {
+            sparklines_registry: {},
+            menus: {},
+            submenu_names: {},
+            data: null,
+            hostname: 'netdata_server', // will be overwritten by the netdata server
+            categories: new Array(),
+            categories_idx: {},
+            families: new Array(),
+            families_idx: {},
+
+            chartsPerRow: 0,
+            chartsMinWidth: 1450,
+            chartsHeight: 180,
+            sparklinesHeight: 60,
+        };
 
-    function sortObjectByPriority(object) {
-        var idx = {};
-        var sorted = new Array();
+        // generate a sparkline
+        // used in the documentation
+        function sparkline(chart, dimension, units) {
+            var key = chart + '.' + dimension;
 
-        for(var i in object) {
-            if(typeof idx[i] === 'undefined') {
-                idx[i] = object[i];
-                sorted.push(i);
-            }
-        }
+            if(typeof units === 'undefined')
+                units = '';
 
-        sorted.sort(function(a, b) {
-            if(idx[a].priority < idx[b].priority) return -1;
-            if(idx[a].priority > idx[b].priority) return 1;
-            if(a < b) return -1;
-            return 1;
-        });
+            if(typeof options.sparklines_registry[key] === 'undefined')
+                options.sparklines_registry[key] = { count: 1 };
+            else
+                options.sparklines_registry[key].count++;
 
-        return sorted;
-    }
+            key = key + '.' + options.sparklines_registry[key].count;
 
+            var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
 
-    // ----------------------------------------------------------------------------
-    // scroll to a section, without changing the browser history
+            return h;
+        }
 
-    function scrollToId(hash) {
-        if(hash && hash != '' && document.getElementById(hash) !== null) {
-            var offset = $('#' + hash).offset();
-            if(typeof offset !== 'undefined')
-                $('html, body').animate({ scrollTop: offset.top }, 0);
+        function chartsPerRow(total) {
+            if(options.chartsPerRow === 0) {
+                width = Math.floor(total / options.chartsMinWidth);
+                if(width === 0) width = 1;
+                return width;
+            }
+            else return options.chartsPerRow;
         }
 
-        // we must return false to prevent the default action
-        return false;
-    }
+        function prioritySort(a, b) {
+            if(a.priority < b.priority) return -1;
+            if(a.priority > b.priority) return 1;
+            if(a.name < b.name) return -1;
+            return 1;
+        }
 
-    // ----------------------------------------------------------------------------
-
-    var netdataDashboard = {
-        menu: {},
-        submenu: {},
-        context: {},
-
-        gaugeChart: function(title, width, dimensions, colors) {
-            if(typeof colors === 'undefined')
-                colors = '';
-
-            if(typeof dimensions === 'undefined')
-                dimensions = '';
-
-            return '<div data-netdata="CHART_UNIQUE_ID"'
-                                    + ' data-dimensions="' + dimensions + '"'
-                                    + ' data-chart-library="gauge"'
-                                    + ' data-gauge-adjust="width"'
-                                    + ' data-title="' + title + '"'
-                                    + ' data-width="' + width + '"'
-                                    + ' data-before="0"'
-                                    + ' data-after="-CHART_DURATION"'
-                                    + ' data-points="CHART_DURATION"'
-                                    + ' data-colors="' + colors + '"'
-                                    + ' role="application"></div>';
-        },
-
-        anyAttribute: function(obj, attr, key, def) {
-            if(typeof obj[key] !== 'undefined') {
-                if(typeof obj[key][attr] !== 'undefined')
-                    return obj[key][attr];
-            }
-            return def;
-        },
+        function sortObjectByPriority(object) {
+            var idx = {};
+            var sorted = new Array();
 
-        menuTitle: function(chart) {
-            if(typeof chart.menu_pattern !== 'undefined') {
-                return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu_pattern, chart.menu_pattern).toString()
-                        + '&nbsp;' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
+            for(var i in object) {
+                if(typeof idx[i] === 'undefined') {
+                    idx[i] = object[i];
+                    sorted.push(i);
+                }
             }
 
-            return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
-        },
-
-        menuIcon: function(chart) {
-            if(typeof chart.menu_pattern !== 'undefined')
-                return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
+            sorted.sort(function(a, b) {
+                if(idx[a].priority < idx[b].priority) return -1;
+                if(idx[a].priority > idx[b].priority) return 1;
+                if(a < b) return -1;
+                return 1;
+            });
 
-            return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
-        },
+            return sorted;
+        }
 
-        menuInfo: function(menu) {
-            return netdataDashboard.anyAttribute(netdataDashboard.menu, 'info', menu, null);
-        },
 
-        menuHeight: function(menu, relative) {
-            return netdataDashboard.anyAttribute(netdataDashboard.menu, 'height', menu, 1.0) * relative;
-        },
+        // ----------------------------------------------------------------------------
+        // scroll to a section, without changing the browser history
 
-        submenuTitle: function(menu, submenu) {
-            var key = menu + '.' + submenu;
-            var title = netdataDashboard.anyAttribute(netdataDashboard.submenu, 'title', key, submenu).toString().replace(/_/g, ' ');;
-            if(title.length > 28) {
-                var a = title.substring(0, 13);
-                var b = title.substring(title.length - 12, title.length);
-                return a + '...' + b;
+        function scrollToId(hash) {
+            if(hash && hash != '' && document.getElementById(hash) !== null) {
+                var offset = $('#' + hash).offset();
+                if(typeof offset !== 'undefined')
+                    $('html, body').animate({ scrollTop: offset.top }, 0);
             }
-            return title;
-        },
-
-        submenuInfo: function(menu, submenu) {
-            var key = menu + '.' + submenu;
-            return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'info', key, null);
-        },
-
-        submenuHeight: function(menu, submenu, relative) {
-            var key = menu + '.' + submenu;
-            return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'height', key, 1.0) * relative;
-        },
-
-        contextInfo: function(id) {
-            if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].info !== 'undefined')
-                return '<div class="chart-message netdata-chart-alignment" role="document">' + netdataDashboard.context[id].info + '</div>';
-            else
-                return '';
-        },
 
-        contextValueRange: function(id) {
-            if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].valueRange !== 'undefined')
-                return netdataDashboard.context[id].valueRange;
-            else
-                return '[null, null]';
-        },
+            // we must return false to prevent the default action
+            return false;
+        }
 
-        contextHeight: function(id, def) {
-            if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].height !== 'undefined')
-                return def * netdataDashboard.context[id].height;
-            else
+        // ----------------------------------------------------------------------------
+
+        var netdataDashboard = {
+            menu: {},
+            submenu: {},
+            context: {},
+
+            gaugeChart: function(title, width, dimensions, colors) {
+                if(typeof colors === 'undefined')
+                    colors = '';
+
+                if(typeof dimensions === 'undefined')
+                    dimensions = '';
+
+                return '<div data-netdata="CHART_UNIQUE_ID"'
+                                        + ' data-dimensions="' + dimensions + '"'
+                                        + ' data-chart-library="gauge"'
+                                        + ' data-gauge-adjust="width"'
+                                        + ' data-title="' + title + '"'
+                                        + ' data-width="' + width + '"'
+                                        + ' data-before="0"'
+                                        + ' data-after="-CHART_DURATION"'
+                                        + ' data-points="CHART_DURATION"'
+                                        + ' data-colors="' + colors + '"'
+                                        + ' role="application"></div>';
+            },
+
+            anyAttribute: function(obj, attr, key, def) {
+                if(typeof obj[key] !== 'undefined') {
+                    if(typeof obj[key][attr] !== 'undefined')
+                        return obj[key][attr];
+                }
                 return def;
-        }
-    };
-
-    // ----------------------------------------------------------------------------
-
-    // enrich the data structure returned by netdata
-    // to reflect our menu system and content
-    function enrichChartData(chart) {
-        var tmp = chart.type.split('_')[0];
-
-        switch(tmp) {
-            case 'ap':
-            case 'net':
-            case 'disk':
-                chart.menu = tmp;
-                break;
-
-            case 'cgroup':
-                chart.menu = chart.type;
-                if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
-                    chart.menu_pattern = 'cgqemu';
-                else
-                    chart.menu_pattern = 'cgroup';
-                break;
-
-            case 'apache':
-            case 'exim':
-            case 'dovecot':
-            case 'hddtemp':
-            case 'ipfs':
-            case 'memcached':
-            case 'mysql':
-            case 'named':
-            case 'nginx':
-            case 'nut':
-            case 'phpfpm':
-            case 'postfix':
-            case 'postgres':
-            case 'redis':
-            case 'retroshare':
-            case 'smawebbox':
-            case 'snmp':
-            case 'squid':
-            case 'tomcat':
-                chart.menu = chart.type;
-                chart.menu_pattern = tmp;
-                break;
-
-            case 'tc':
-                chart.menu = tmp;
-
-                // find a name for this device from fireqos info
-                // we strip '_(in|out)' or '(in|out)_'
-                if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
-                    var n = chart.name.split('.')[1];
-                    if(n.endsWith('_in'))
-                        options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
-                    else if(n.endsWith('_out'))
-                        options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
-                    else if(n.startsWith('in_'))
-                        options.submenu_names[chart.family] = n.slice(3, n.length);
-                    else if(n.startsWith('out_'))
-                        options.submenu_names[chart.family] = n.slice(4, n.length);
+            },
+
+            menuTitle: function(chart) {
+                if(typeof chart.menu_pattern !== 'undefined') {
+                    return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu_pattern, chart.menu_pattern).toString()
+                            + '&nbsp;' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
                 }
 
-                // increase the priority of IFB devices
-                // to have inbound appear before outbound
-                if(chart.id.match(/.*-ifb$/))
-                    chart.priority--;
+                return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
+            },
 
-                break;
+            menuIcon: function(chart) {
+                if(typeof chart.menu_pattern !== 'undefined')
+                    return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
 
-            default:
-                chart.menu = chart.type;
-                break;
-        }
+                return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
+            },
 
-        chart.submenu = chart.family;
-    }
+            menuInfo: function(menu) {
+                return netdataDashboard.anyAttribute(netdataDashboard.menu, 'info', menu, null);
+            },
 
-    // ----------------------------------------------------------------------------
-
-    function headMain(charts, duration) {
-        var head = '';
-
-        if(typeof charts['system.swap'] !== 'undefined')
-            head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
-            + ' data-dimensions="used"'
-            + ' data-append-options="percentage"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="Used Swap"'
-            + ' data-units="%"'
-            + ' data-easypiechart-max-value="100"'
-            + ' data-width="8%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' data-colors="#DD4400"'
-            + ' role="application"></div>';
-
-        if(typeof charts['system.io'] !== 'undefined') {
-            head += '<div style="margin-right: 10px;" data-netdata="system.io"'
-            + ' data-dimensions="in"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="Disk Read"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-
-            head += '<div style="margin-right: 10px;" data-netdata="system.io"'
-            + ' data-dimensions="out"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="Disk Write"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-        }
+            menuHeight: function(menu, relative) {
+                return netdataDashboard.anyAttribute(netdataDashboard.menu, 'height', menu, 1.0) * relative;
+            },
 
-        if(typeof charts['system.cpu'] !== 'undefined')
-            head += '<div data-netdata="system.cpu"'
-            + ' data-chart-library="gauge"'
-            + ' data-title="CPU"'
-            + ' data-units="%"'
-            + ' data-gauge-max-value="100"'
-            + ' data-width="18%"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' data-colors="' + NETDATA.colors[12] + '"'
-            + ' role="application"></div>';
-
-        if(typeof charts['system.ipv4'] !== 'undefined') {
-            head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
-            + ' data-dimensions="received"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="IPv4 Inbound"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-
-            head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
-            + ' data-dimensions="sent"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="IPv4 Outbound"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-        }
-        else if(typeof charts['system.ipv6'] !== 'undefined') {
-            head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
-            + ' data-dimensions="received"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="IPv6 Inbound"'
-            + ' data-units="kbps"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-
-            head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
-            + ' data-dimensions="sent"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="IPv6 Outbound"'
-            + ' data-units="kbps"'
-            + ' data-width="10%"'
-            + ' data-before="0"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' role="application"></div>';
-        }
+            submenuTitle: function(menu, submenu) {
+                var key = menu + '.' + submenu;
+                var title = netdataDashboard.anyAttribute(netdataDashboard.submenu, 'title', key, submenu).toString().replace(/_/g, ' ');;
+                if(title.length > 28) {
+                    var a = title.substring(0, 13);
+                    var b = title.substring(title.length - 12, title.length);
+                    return a + '...' + b;
+                }
+                return title;
+            },
+
+            submenuInfo: function(menu, submenu) {
+                var key = menu + '.' + submenu;
+                return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'info', key, null);
+            },
+
+            submenuHeight: function(menu, submenu, relative) {
+                var key = menu + '.' + submenu;
+                return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'height', key, 1.0) * relative;
+            },
+
+            contextInfo: function(id) {
+                if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].info !== 'undefined')
+                    return '<div class="chart-message netdata-chart-alignment" role="document">' + netdataDashboard.context[id].info + '</div>';
+                else
+                    return '';
+            },
 
-        if(typeof charts['system.ram'] !== 'undefined')
-            head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
-            + ' data-dimensions="used|buffers|active|wired"' // active and wired are FreeBSD stats
-            + ' data-append-options="percentage"'
-            + ' data-chart-library="easypiechart"'
-            + ' data-title="Used RAM"'
-            + ' data-units="%"'
-            + ' data-easypiechart-max-value="100"'
-            + ' data-width="8%"'
-            + ' data-after="-' + duration.toString() + '"'
-            + ' data-points="' + duration.toString() + '"'
-            + ' data-colors="' + NETDATA.colors[7] + '"'
-            + ' role="application"></div>';
-
-        return head;
-    }
+            contextValueRange: function(id) {
+                if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].valueRange !== 'undefined')
+                    return netdataDashboard.context[id].valueRange;
+                else
+                    return '[null, null]';
+            },
 
-    function generateHeadCharts(type, chart, duration) {
-        var head = '';
-        var hcharts = netdataDashboard.anyAttribute(netdataDashboard.context, type, chart.context, []);
-        if(hcharts.length > 0) {
-            var hi = 0, hlen = hcharts.length;
-            while(hi < hlen) {
-                if(typeof hcharts[hi] === 'function')
-                    head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
+            contextHeight: function(id, def) {
+                if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].height !== 'undefined')
+                    return def * netdataDashboard.context[id].height;
                 else
-                    head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
-                hi++;
+                    return def;
             }
-        }
-        return head;
-    }
+        };
 
-    function renderPage(menus, data) {
-        var div = document.getElementById('charts_div');
-        var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
-
-        // find the proper duration for per-second updates
-        var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
-        var html = '';
-        var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
-        var mainhead = headMain(data.charts, duration);
-
-        // sort the menus
-        var main = sortObjectByPriority(menus);
-        var i = 0, len = main.length;
-        while(i < len) {
-            var menu = main[i++];
-
-            // generate an entry at the main menu
-
-            var menuid = NETDATA.name2id('menu_' + menu);
-            sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
-            html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">';
-
-            if(menus[menu].info !== null)
-                html += menus[menu].info;
-
-            // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
-
-            var shtml = '';
-            var mhead = '<div class="netdata-chart-row">' + mainhead;
-            mainhead = '';
-
-            // sort the submenus of this menu
-            var sub = sortObjectByPriority(menus[menu].submenus);
-            var si = 0, slen = sub.length;
-            while(si < slen) {
-                var submenu = sub[si++];
-
-                // generate an entry at the submenu
-                var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu);
-                sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
-                shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
-
-                if(menus[menu].submenus[submenu].info !== null)
-                    shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
-
-                var head = '<div class="netdata-chart-row">';
-                var chtml = '';
-
-                // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
-
-                // sort the charts in this submenu of this menu
-                menus[menu].submenus[submenu].charts.sort(prioritySort);
-                var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
-                while(ci < clen) {
-                    var chart = menus[menu].submenus[submenu].charts[ci++];
-
-                    // generate the submenu heading charts
-                    mhead += generateHeadCharts('mainheads', chart, duration);
-                    head += generateHeadCharts('heads', chart, duration);
-
-                    // generate the chart
-                    chtml += netdataDashboard.contextInfo(chart.context) + '<div id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
-                        + ' data-width="' + pcent_width.toString() + '%"'
-                        + ' data-height="' + netdataDashboard.contextHeight(chart.context, options.chartsHeight).toString() + 'px"'
-                        + ' data-dygraph-valuerange="' + netdataDashboard.contextValueRange(chart.context) + '"'
-                        + ' data-before="0"'
-                        + ' data-after="-' + duration.toString() + '"'
-                        + ' data-id="' + NETDATA.name2id(options.hostname + '/' + chart.id) + '"'
-                        + ' data-colors="' + netdataDashboard.anyAttribute(netdataDashboard.context, 'colors', chart.context, '') + '"'
-                        + ' role="application"></div>';
-
-                    // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
-                }
+        // ----------------------------------------------------------------------------
 
-                head += '</div>';
-                shtml += head + chtml + '</div>';
-            }
+        // enrich the data structure returned by netdata
+        // to reflect our menu system and content
+        function enrichChartData(chart) {
+            var tmp = chart.type.split('_')[0];
 
-            mhead += '</div>';
-            sidebar += '</ul></li>';
-            html += mhead + shtml + '</div></div><hr role="separator"/>';
-        }
+            switch(tmp) {
+                case 'ap':
+                case 'net':
+                case 'disk':
+                    chart.menu = tmp;
+                    break;
 
-        sidebar += '<li class="" style="padding-top:15px;"><a href="https://github.com/firehol/netdata/wiki/Add-more-charts-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more charts</a></li>';
-        sidebar += '<li class=""><a href="https://github.com/firehol/netdata/wiki/Add-more-alarms-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more alarms</a></li>';
-        sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every == 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + Math.round(data.history / 3600).toLocaleString() + ' ' + ((data.history == 3600)?'hour':'hours').toString() + ' of real-time history.</small></li>';
-        sidebar += '</ul>';
-        div.innerHTML = html;
-        document.getElementById('sidebar').innerHTML = sidebar;
-        finalizePage();
-    }
+                case 'cgroup':
+                    chart.menu = chart.type;
+                    if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
+                        chart.menu_pattern = 'cgqemu';
+                    else
+                        chart.menu_pattern = 'cgroup';
+                    break;
+
+                case 'apache':
+                case 'exim':
+                case 'dovecot':
+                case 'hddtemp':
+                case 'ipfs':
+                case 'memcached':
+                case 'mysql':
+                case 'named':
+                case 'nginx':
+                case 'nut':
+                case 'phpfpm':
+                case 'postfix':
+                case 'postgres':
+                case 'redis':
+                case 'retroshare':
+                case 'smawebbox':
+                case 'snmp':
+                case 'squid':
+                case 'tomcat':
+                    chart.menu = chart.type;
+                    chart.menu_pattern = tmp;
+                    break;
+
+                case 'tc':
+                    chart.menu = tmp;
+
+                    // find a name for this device from fireqos info
+                    // we strip '_(in|out)' or '(in|out)_'
+                    if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
+                        var n = chart.name.split('.')[1];
+                        if(n.endsWith('_in'))
+                            options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
+                        else if(n.endsWith('_out'))
+                            options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
+                        else if(n.startsWith('in_'))
+                            options.submenu_names[chart.family] = n.slice(3, n.length);
+                        else if(n.startsWith('out_'))
+                            options.submenu_names[chart.family] = n.slice(4, n.length);
+                    }
 
-    function renderChartsAndMenu(data) {
-        var menus = options.menus;
-        var charts = data.charts;
-
-        for(var c in charts) {
-            enrichChartData(charts[c]);
-
-            // create the menu
-            if(typeof menus[charts[c].menu] === 'undefined') {
-                menus[charts[c].menu] = {
-                    priority: charts[c].priority,
-                    submenus: {},
-                    title: netdataDashboard.menuTitle(charts[c]),
-                    icon: netdataDashboard.menuIcon(charts[c]),
-                    info: netdataDashboard.menuInfo(charts[c].menu),
-                    height: netdataDashboard.menuHeight(charts[c].menu, options.chartsHeight)
-                };
+                    // increase the priority of IFB devices
+                    // to have inbound appear before outbound
+                    if(chart.id.match(/.*-ifb$/))
+                        chart.priority--;
+
+                    break;
+
+                default:
+                    chart.menu = chart.type;
+                    break;
             }
 
-            if(charts[c].priority < menus[charts[c].menu].priority)
-                menus[charts[c].menu].priority = charts[c].priority;
-
-            // create the submenu
-            if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
-                menus[charts[c].menu].submenus[charts[c].submenu] = {
-                    priority: charts[c].priority,
-                    charts: new Array(),
-                    title: null,
-                    info: netdataDashboard.submenuInfo(charts[c].menu, charts[c].submenu),
-                    height: netdataDashboard.submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
-                };
+            chart.submenu = chart.family;
+        }
+
+        // ----------------------------------------------------------------------------
+
+        function headMain(charts, duration) {
+            var head = '';
+
+            if(typeof charts['system.swap'] !== 'undefined')
+                head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
+                + ' data-dimensions="used"'
+                + ' data-append-options="percentage"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="Used Swap"'
+                + ' data-units="%"'
+                + ' data-easypiechart-max-value="100"'
+                + ' data-width="8%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' data-colors="#DD4400"'
+                + ' role="application"></div>';
+
+            if(typeof charts['system.io'] !== 'undefined') {
+                head += '<div style="margin-right: 10px;" data-netdata="system.io"'
+                + ' data-dimensions="in"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="Disk Read"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
+
+                head += '<div style="margin-right: 10px;" data-netdata="system.io"'
+                + ' data-dimensions="out"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="Disk Write"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
             }
 
-            if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
-                menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
+            if(typeof charts['system.cpu'] !== 'undefined')
+                head += '<div data-netdata="system.cpu"'
+                + ' data-chart-library="gauge"'
+                + ' data-title="CPU"'
+                + ' data-units="%"'
+                + ' data-gauge-max-value="100"'
+                + ' data-width="18%"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' data-colors="' + NETDATA.colors[12] + '"'
+                + ' role="application"></div>';
+
+            if(typeof charts['system.ipv4'] !== 'undefined') {
+                head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
+                + ' data-dimensions="received"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="IPv4 Inbound"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
+
+                head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
+                + ' data-dimensions="sent"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="IPv4 Outbound"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
+            }
+            else if(typeof charts['system.ipv6'] !== 'undefined') {
+                head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
+                + ' data-dimensions="received"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="IPv6 Inbound"'
+                + ' data-units="kbps"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
+
+                head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
+                + ' data-dimensions="sent"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="IPv6 Outbound"'
+                + ' data-units="kbps"'
+                + ' data-width="10%"'
+                + ' data-before="0"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' role="application"></div>';
+            }
 
-            // index the chart in the menu/submenu
-            menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
+            if(typeof charts['system.ram'] !== 'undefined')
+                head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
+                + ' data-dimensions="used|buffers|active|wired"' // active and wired are FreeBSD stats
+                + ' data-append-options="percentage"'
+                + ' data-chart-library="easypiechart"'
+                + ' data-title="Used RAM"'
+                + ' data-units="%"'
+                + ' data-easypiechart-max-value="100"'
+                + ' data-width="8%"'
+                + ' data-after="-' + duration.toString() + '"'
+                + ' data-points="' + duration.toString() + '"'
+                + ' data-colors="' + NETDATA.colors[7] + '"'
+                + ' role="application"></div>';
+
+            return head;
         }
 
-        // propagate the descriptive subname given to QoS
-        // to all the other submenus with the same name
-        for(var m in menus) {
-            for(var s in menus[m].submenus) {
-                // set the family using a name
-                if(typeof options.submenu_names[s] !== 'undefined') {
-                    menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
-                }
-                else {
-                    menus[m].submenus[s].title = netdataDashboard.submenuTitle(m, s);
+        function generateHeadCharts(type, chart, duration) {
+            var head = '';
+            var hcharts = netdataDashboard.anyAttribute(netdataDashboard.context, type, chart.context, []);
+            if(hcharts.length > 0) {
+                var hi = 0, hlen = hcharts.length;
+                while(hi < hlen) {
+                    if(typeof hcharts[hi] === 'function')
+                        head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
+                    else
+                        head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
+                    hi++;
                 }
             }
+            return head;
         }
 
-        renderPage(menus, data);
-    }
+        function renderPage(menus, data) {
+            var div = document.getElementById('charts_div');
+            var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
+
+            // find the proper duration for per-second updates
+            var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
+            var html = '';
+            var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
+            var mainhead = headMain(data.charts, duration);
+
+            // sort the menus
+            var main = sortObjectByPriority(menus);
+            var i = 0, len = main.length;
+            while(i < len) {
+                var menu = main[i++];
+
+                // generate an entry at the main menu
+
+                var menuid = NETDATA.name2id('menu_' + menu);
+                sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
+                html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">';
+
+                if(menus[menu].info !== null)
+                    html += menus[menu].info;
+
+                // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
+
+                var shtml = '';
+                var mhead = '<div class="netdata-chart-row">' + mainhead;
+                mainhead = '';
+
+                // sort the submenus of this menu
+                var sub = sortObjectByPriority(menus[menu].submenus);
+                var si = 0, slen = sub.length;
+                while(si < slen) {
+                    var submenu = sub[si++];
+
+                    // generate an entry at the submenu
+                    var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu);
+                    sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
+                    shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
+
+                    if(menus[menu].submenus[submenu].info !== null)
+                        shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
+
+                    var head = '<div class="netdata-chart-row">';
+                    var chtml = '';
+
+                    // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
+
+                    // sort the charts in this submenu of this menu
+                    menus[menu].submenus[submenu].charts.sort(prioritySort);
+                    var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
+                    while(ci < clen) {
+                        var chart = menus[menu].submenus[submenu].charts[ci++];
+
+                        // generate the submenu heading charts
+                        mhead += generateHeadCharts('mainheads', chart, duration);
+                        head += generateHeadCharts('heads', chart, duration);
+
+                        // generate the chart
+                        chtml += netdataDashboard.contextInfo(chart.context) + '<div id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
+                            + ' data-width="' + pcent_width.toString() + '%"'
+                            + ' data-height="' + netdataDashboard.contextHeight(chart.context, options.chartsHeight).toString() + 'px"'
+                            + ' data-dygraph-valuerange="' + netdataDashboard.contextValueRange(chart.context) + '"'
+                            + ' data-before="0"'
+                            + ' data-after="-' + duration.toString() + '"'
+                            + ' data-id="' + NETDATA.name2id(options.hostname + '/' + chart.id) + '"'
+                            + ' data-colors="' + netdataDashboard.anyAttribute(netdataDashboard.context, 'colors', chart.context, '') + '"'
+                            + ' role="application"></div>';
+
+                        // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
+                    }
 
-    // ----------------------------------------------------------------------------
-
-    function loadJs(url, callback) {
-        $.ajax({
-            url: url,
-            cache: true,
-            dataType: "script",
-            xhrFields: { withCredentials: true } // required for the cookie
-        })
-        .fail(function() {
-            alert('Cannot load required JS library: ' + url);
-        })
-        .always(function() {
-            if(typeof callback === 'function')
-                callback();
-        })
-    }
+                    head += '</div>';
+                    shtml += head + chtml + '</div>';
+                }
 
-    var bootstrapTableLoaded = false;
-    function loadBootstrapTable(callback) {
-        if(bootstrapTableLoaded === false) {
-            bootstrapTableLoaded === true;
-            loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-1.11.0.min.js', function() {
-                loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-export-1.11.0.min.js', function() {
-                    loadJs(NETDATA.serverDefault + 'lib/tableExport-1.6.0.min.js', callback);
-                })
-            });
+                mhead += '</div>';
+                sidebar += '</ul></li>';
+                html += mhead + shtml + '</div></div><hr role="separator"/>';
+            }
+
+            sidebar += '<li class="" style="padding-top:15px;"><a href="https://github.com/firehol/netdata/wiki/Add-more-charts-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more charts</a></li>';
+            sidebar += '<li class=""><a href="https://github.com/firehol/netdata/wiki/Add-more-alarms-to-netdata" target="_blank"><i class="fa fa-plus" aria-hidden="true"></i> add more alarms</a></li>';
+            sidebar += '<li class="" style="margin:20px;color:#666;"><small>netdata on <b>' + data.hostname.toString() + '</b>, collects every ' + ((data.update_every == 1)?'second':data.update_every.toString() + ' seconds') + ' <b>' + data.dimensions_count.toLocaleString() + '</b> metrics, presented as <b>' + data.charts_count.toLocaleString() + '</b> charts and monitored by <b>' + data.alarms_count.toLocaleString() + '</b> alarms, using ' + Math.round(data.rrd_memory_bytes / 1024 / 1024).toLocaleString() + ' MB of memory for ' + Math.round(data.history / (3600/data.update_every)).toLocaleString() + ' ' + ((data.history == (3600/data.update_every))?'hour':'hours').toString() + ' of real-time history.</small></li>';
+            sidebar += '</ul>';
+            div.innerHTML = html;
+            document.getElementById('sidebar').innerHTML = sidebar;
+            finalizePage();
         }
-        else callback();
-    }
 
-    function alarmsUpdateModal() {
-        var active = '<h3>Raised Alarms</h3><table class="table">';
-        var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
-        var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b>&nbsp;red&nbsp;</b></span> is critical, <span style="color:#fe7d37"><b>&nbsp;orange&nbsp;</b></span> is warning, <span style="color: #4c1"><b>&nbsp;bright green&nbsp;</b></span> is ok, <span style="color: #9f9f9f"><b>&nbsp;light grey&nbsp;</b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b>&nbsp;black&nbsp;</b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.<br/>netdata can send notifications for these alarms. Check <a href="https://github.com/firehol/netdata/blob/master/conf.d/health_alarm_notify.conf">this configuration file</a> for more information.';
+        function renderChartsAndMenu(data) {
+            var menus = options.menus;
+            var charts = data.charts;
+
+            for(var c in charts) {
+                enrichChartData(charts[c]);
+
+                // create the menu
+                if(typeof menus[charts[c].menu] === 'undefined') {
+                    menus[charts[c].menu] = {
+                        priority: charts[c].priority,
+                        submenus: {},
+                        title: netdataDashboard.menuTitle(charts[c]),
+                        icon: netdataDashboard.menuIcon(charts[c]),
+                        info: netdataDashboard.menuInfo(charts[c].menu),
+                        height: netdataDashboard.menuHeight(charts[c].menu, options.chartsHeight)
+                    };
+                }
 
-        NETDATA.alarms.get('all', function(data) {
-            options.alarm_families = new Array();
+                if(charts[c].priority < menus[charts[c].menu].priority)
+                    menus[charts[c].menu].priority = charts[c].priority;
+
+                // create the submenu
+                if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
+                    menus[charts[c].menu].submenus[charts[c].submenu] = {
+                        priority: charts[c].priority,
+                        charts: new Array(),
+                        title: null,
+                        info: netdataDashboard.submenuInfo(charts[c].menu, charts[c].submenu),
+                        height: netdataDashboard.submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
+                    };
+                }
 
-            alarmsCallback(data);
+                if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
+                    menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
 
-            if(data === null) {
-                document.getElementById('alarms_active').innerHTML =
-                        document.getElementById('alarms_all').innerHTML =
-                                document.getElementById('alarms_log').innerHTML =
-                                        'failed to load alarm data!';
-                return;
+                // index the chart in the menu/submenu
+                menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
             }
 
-            function alarmid4human(id) {
-                if(id === 0)
-                    return '-';
-
-                return id.toString();
+            // propagate the descriptive subname given to QoS
+            // to all the other submenus with the same name
+            for(var m in menus) {
+                for(var s in menus[m].submenus) {
+                    // set the family using a name
+                    if(typeof options.submenu_names[s] !== 'undefined') {
+                        menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
+                    }
+                    else {
+                        menus[m].submenus[s].title = netdataDashboard.submenuTitle(m, s);
+                    }
+                }
             }
 
-            function timestamp4human(timestamp, space) {
-                if(timestamp === 0)
-                    return '-';
+            renderPage(menus, data);
+        }
 
-                if(typeof space === 'undefined')
-                    space = '&nbsp;';
+        // ----------------------------------------------------------------------------
+
+        function loadJs(url, callback) {
+            $.ajax({
+                url: url,
+                cache: true,
+                dataType: "script",
+                xhrFields: { withCredentials: true } // required for the cookie
+            })
+            .fail(function() {
+                alert('Cannot load required JS library: ' + url);
+            })
+            .always(function() {
+                if(typeof callback === 'function')
+                    callback();
+            })
+        }
 
-                var t = new Date(timestamp * 1000);
-                var now = new Date();
+        var bootstrapTableLoaded = false;
+        function loadBootstrapTable(callback) {
+            if(bootstrapTableLoaded === false) {
+                bootstrapTableLoaded === true;
+                loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-1.11.0.min.js', function() {
+                    loadJs(NETDATA.serverDefault + 'lib/bootstrap-table-export-1.11.0.min.js', function() {
+                        loadJs(NETDATA.serverDefault + 'lib/tableExport-1.6.0.min.js', callback);
+                    })
+                });
+            }
+            else callback();
+        }
 
-                if(t.toDateString() == now.toDateString())
-                    return t.toLocaleTimeString();
+        function alarmsUpdateModal() {
+            var active = '<h3>Raised Alarms</h3><table class="table">';
+            var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
+            var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b>&nbsp;red&nbsp;</b></span> is critical, <span style="color:#fe7d37"><b>&nbsp;orange&nbsp;</b></span> is warning, <span style="color: #4c1"><b>&nbsp;bright green&nbsp;</b></span> is ok, <span style="color: #9f9f9f"><b>&nbsp;light grey&nbsp;</b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b>&nbsp;black&nbsp;</b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.<br/>netdata can send notifications for these alarms. Check <a href="https://github.com/firehol/netdata/blob/master/conf.d/health_alarm_notify.conf">this configuration file</a> for more information.';
 
-                return t.toLocaleDateString() + space + t.toLocaleTimeString();
-            }
+            NETDATA.alarms.get('all', function(data) {
+                options.alarm_families = new Array();
 
-            function seconds4human(seconds, options) {
-                var default_options = {
-                    now: 'now',
-                    space: '&nbsp;',
-                    negative_suffix: 'ago',
-                    hour: 'hour',
-                    hours: 'hours',
-                    minute: 'minute',
-                    minutes: 'minutes',
-                    second: 'second',
-                    seconds: 'seconds',
-                    and: 'and'
-                };
+                alarmsCallback(data);
 
-                if(typeof options !== 'object')
-                    options = default_options;
-                else {
-                    var x;
-                    for(x in default_options) {
-                        if(typeof options[x] !== 'string')
-                            options[x] = default_options[x];
-                    }
+                if(data === null) {
+                    document.getElementById('alarms_active').innerHTML =
+                            document.getElementById('alarms_all').innerHTML =
+                                    document.getElementById('alarms_log').innerHTML =
+                                            'failed to load alarm data!';
+                    return;
+                }
+
+                function alarmid4human(id) {
+                    if(id === 0)
+                        return '-';
+
+                    return id.toString();
                 }
 
-                if(typeof seconds === 'string')
-                    seconds = parseInt(seconds);
+                function timestamp4human(timestamp, space) {
+                    if(timestamp === 0)
+                        return '-';
 
-                if(seconds === 0)
-                    return options.now;
+                    if(typeof space === 'undefined')
+                        space = '&nbsp;';
 
-                var suffix = '';
-                if(seconds < 0) {
-                    seconds = -seconds;
-                    if(options.negative_suffix !== '') suffix = options.space + options.negative_suffix;
+                    var t = new Date(timestamp * 1000);
+                    var now = new Date();
+
+                    if(t.toDateString() == now.toDateString())
+                        return t.toLocaleTimeString();
+
+                    return t.toLocaleDateString() + space + t.toLocaleTimeString();
                 }
 
-                var hours = Math.floor(seconds / 3600);
-                seconds -= (hours * 3600);
+                function seconds4human(seconds, options) {
+                    var default_options = {
+                        now: 'now',
+                        space: '&nbsp;',
+                        negative_suffix: 'ago',
+                        hour: 'hour',
+                        hours: 'hours',
+                        minute: 'minute',
+                        minutes: 'minutes',
+                        second: 'second',
+                        seconds: 'seconds',
+                        and: 'and'
+                    };
+
+                    if(typeof options !== 'object')
+                        options = default_options;
+                    else {
+                        var x;
+                        for(x in default_options) {
+                            if(typeof options[x] !== 'string')
+                                options[x] = default_options[x];
+                        }
+                    }
 
-                var minutes = Math.floor(seconds / 60);
-                seconds -= (minutes * 60);
+                    if(typeof seconds === 'string')
+                        seconds = parseInt(seconds);
 
-                var txt = '';
+                    if(seconds === 0)
+                        return options.now;
 
-                if(hours > 1) txt += hours.toString() + options.space + options.hours;
-                else if(hours === 1) txt += hours.toString() + options.space + options.hour;
+                    var suffix = '';
+                    if(seconds < 0) {
+                        seconds = -seconds;
+                        if(options.negative_suffix !== '') suffix = options.space + options.negative_suffix;
+                    }
 
-                if(hours > 0 && minutes > 0 && seconds == 0)
-                    txt += options.space + options.and + options.space;
-                else if(hours > 0 && minutes > 0 && seconds > 0)
-                    txt += ',' + options.space;
+                    var hours = Math.floor(seconds / 3600);
+                    seconds -= (hours * 3600);
 
-                if(minutes > 1) txt += minutes.toString() + options.space + options.minutes;
-                else if(minutes === 1) txt += minutes.toString() + options.space + options.minute;
+                    var minutes = Math.floor(seconds / 60);
+                    seconds -= (minutes * 60);
 
-                if((minutes > 0 || minutes > 0) && seconds > 0)
-                    txt += options.space + options.and + options.space;
+                    var txt = '';
 
-                if(seconds > 1) txt += Math.floor(seconds).toString() + options.space + options.seconds;
-                else if(seconds === 1) txt += Math.floor(seconds).toString() + options.space + options.second;
+                    if(hours > 1) txt += hours.toString() + options.space + options.hours;
+                    else if(hours === 1) txt += hours.toString() + options.space + options.hour;
 
-                return txt + suffix;
-            }
+                    if(hours > 0 && minutes > 0 && seconds == 0)
+                        txt += options.space + options.and + options.space;
+                    else if(hours > 0 && minutes > 0 && seconds > 0)
+                        txt += ',' + options.space;
 
-            function alarm_lookup_explain(alarm, chart) {
-                var dimensions = ' of all values ';
+                    if(minutes > 1) txt += minutes.toString() + options.space + options.minutes;
+                    else if(minutes === 1) txt += minutes.toString() + options.space + options.minute;
 
-                if(chart.dimensions.length > 1)
-                    dimensions = ' of the sum of all dimensions ';
+                    if((minutes > 0 || minutes > 0) && seconds > 0)
+                        txt += options.space + options.and + options.space;
 
-                if(typeof alarm.lookup_dimensions !== 'undefined') {
-                    var d = alarm.lookup_dimensions.replace('|', ',');
-                    var x = d.split(',');
-                    if(x.length > 1)
-                        dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code> ';
-                    else
-                        dimensions = 'of all values of dimension <code>' + alarm.lookup_dimensions + '</code> ';
+                    if(seconds > 1) txt += Math.floor(seconds).toString() + options.space + options.seconds;
+                    else if(seconds === 1) txt += Math.floor(seconds).toString() + options.space + options.second;
+
+                    return txt + suffix;
                 }
 
-                return '<code>' + alarm.lookup_method + '</code> '
-                    + dimensions + ', of chart <code>' + alarm.chart + '</code>'
-                    + ', starting <code>' + seconds4human(alarm.lookup_after + alarm.lookup_before) + '</code> and up to <code>' + seconds4human(alarm.lookup_before) + '</code>'
-                    + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ',&nbsp;') + '</code>'):'')
-                    + '.';
-            }
+                function alarm_lookup_explain(alarm, chart) {
+                    var dimensions = ' of all values ';
 
-            function alarm_to_html(alarm, full) {
-                var chart = options.data.charts[alarm.chart];
+                    if(chart.dimensions.length > 1)
+                        dimensions = ' of the sum of all dimensions ';
 
-                var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/>&nbsp;<br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/>&nbsp;<br/><span style="font-size: 18px">' + alarm.info + '</span><br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small>&nbsp;&nbsp;<a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small></td>'
-                    + '<td><table class="table">'
-                    + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning&nbsp;when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
-                    + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical&nbsp;when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
+                    if(typeof alarm.lookup_dimensions !== 'undefined') {
+                        var d = alarm.lookup_dimensions.replace('|', ',');
+                        var x = d.split(',');
+                        if(x.length > 1)
+                            dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code> ';
+                        else
+                            dimensions = 'of all values of dimension <code>' + alarm.lookup_dimensions + '</code> ';
+                    }
 
-                if(full === true) {
-                        html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
-                        + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
-                        + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
-                        + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
+                    return '<code>' + alarm.lookup_method + '</code> '
+                        + dimensions + ', of chart <code>' + alarm.chart + '</code>'
+                        + ', starting <code>' + seconds4human(alarm.lookup_after + alarm.lookup_before) + '</code> and up to <code>' + seconds4human(alarm.lookup_before) + '</code>'
+                        + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ',&nbsp;') + '</code>'):'')
+                        + '.';
                 }
 
-                var delay = '';
-                if((alarm.delay_up_duration > 0 || alarm.delay_down_duration > 0) && alarm.delay_multiplier != 0 && alarm.delay_max_duration > 0) {
-                    if(alarm.delay_up_duration == alarm.delay_down_duration) {
-                        delay += '<small><br/>hysteresis ' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' });
+                function alarm_to_html(alarm, full) {
+                    var chart = options.data.charts[alarm.chart];
+                    var has_alarm = ((typeof alarm.warn !== 'undefined' || typeof alarm.crit !== 'undefined')?true:false);
+
+                    var role_href = ((has_alarm === true)?('<br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small>&nbsp;&nbsp;<a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small>'):('&nbsp;'));
+
+                    var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/>&nbsp;<br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/>&nbsp;<br/><span style="font-size: 18px">' + alarm.info + '</span>' + role_href + '</td>'
+                        + '<td><table class="table">'
+                        + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning&nbsp;when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
+                        + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical&nbsp;when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
+
+                    if(full === true) {
+                            html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
+                            + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
+                            + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
+                            + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
                     }
-                    else {
-                        delay = '<small><br/>hysteresis ';
-                        if(alarm.delay_up_duration > 0) {
-                            delay += 'on&nbsp;escalation&nbsp;<code>' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' }) + '</code>, ';
+
+                    var delay = '';
+                    if((alarm.delay_up_duration > 0 || alarm.delay_down_duration > 0) && alarm.delay_multiplier != 0 && alarm.delay_max_duration > 0) {
+                        if(alarm.delay_up_duration == alarm.delay_down_duration) {
+                            delay += '<small><br/>hysteresis ' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' });
                         }
-                        if(alarm.delay_down_duration > 0) {
-                            delay += 'on&nbsp;recovery&nbsp;<code>' + seconds4human(alarm.delay_down_duration, { negative_suffix: '' }) + '</code>, ';
+                        else {
+                            delay = '<small><br/>hysteresis ';
+                            if(alarm.delay_up_duration > 0) {
+                                delay += 'on&nbsp;escalation&nbsp;<code>' + seconds4human(alarm.delay_up_duration, { negative_suffix: '' }) + '</code>, ';
+                            }
+                            if(alarm.delay_down_duration > 0) {
+                                delay += 'on&nbsp;recovery&nbsp;<code>' + seconds4human(alarm.delay_down_duration, { negative_suffix: '' }) + '</code>, ';
+                            }
                         }
+                        if(alarm.delay_multiplier != 1.0) {
+                            delay += 'multiplied&nbsp;by&nbsp;<code>' + alarm.delay_multiplier.toString() + '</code>';
+                            delay += ',&nbsp;up&nbsp;to&nbsp;<code>' + seconds4human(alarm.delay_max_duration, { negative_suffix: '' }) + '</code>';
+                        }
+                        delay += '</small>';
                     }
-                    if(alarm.delay_multiplier != 1.0) {
-                        delay += 'multiplied&nbsp;by&nbsp;<code>' + alarm.delay_multiplier.toString() + '</code>';
-                        delay += ',&nbsp;up&nbsp;to&nbsp;<code>' + seconds4human(alarm.delay_max_duration, { negative_suffix: '' }) + '</code>';
-                    }
-                    delay += '</small>';
-                }
 
-                html += '<tr><td width="10%" style="text-align:right">check&nbsp;every</td><td>' + seconds4human(alarm.update_every, { negative_suffix: '' }) + '</td></tr>'
-                    + '<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'
-                    + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
-                    + '</table></td></tr>';
+                    html += '<tr><td width="10%" style="text-align:right">check&nbsp;every</td><td>' + seconds4human(alarm.update_every, { negative_suffix: '' }) + '</td></tr>'
+                        + ((has_alarm === true)?('<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'):'')
+                        + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
+                        + '</table></td></tr>';
 
-                return html;
-            }
-
-            function alarm_family_show(id) {
-                var html = '<table class="table">';
-                var family = options.alarm_families[id];
-                var len = family.arr.length;
-                while(len--) {
-                    var alarm = family.arr[len];
-                    html += alarm_to_html(alarm, true);
+                    return html;
                 }
-                html += '</table>';
-
-                $('#alarm_all_' + id.toString()).html(html);
-            }
-
-            // find the proper family of each alarm
-            var now = Date.now();
-            var x;
-            var count_active = 0;
-            var count_all = 0;
-            var families = {};
-            var families_sort = new Array();
-            for(x in data.alarms) {
-                var alarm = data.alarms[x];
-                var family = alarm.family;
 
-                // find the chart
-                var chart = options.data.charts[alarm.chart];
-                if(typeof chart === 'undefined')
-                    chart = options.data.charts_by_name[alarm.chart];
+                function alarm_family_show(id) {
+                    var html = '<table class="table">';
+                    var family = options.alarm_families[id];
+                    var len = family.arr.length;
+                    while(len--) {
+                        var alarm = family.arr[len];
+                        html += alarm_to_html(alarm, true);
+                    }
+                    html += '</table>';
 
-                // not found - this should never happen!
-                if(typeof chart === 'undefined') {
-                    console.log('WARNING: alarm ' + x + ' is linked to chart ' + alarm.chart + ', which is not found in the list of chart got from the server.');
-                    chart = { priority: 9999999 };
+                    $('#alarm_all_' + id.toString()).html(html);
                 }
-                else if(typeof chart.menu !== 'undefined' && typeof chart.submenu !== 'undefined')
-                    // the family based on the chart
-                    family = chart.menu + ' - ' + chart.submenu;
-
-                if(typeof families[family] === 'undefined') {
-                    families[family] = {
-                        name: family,
-                        arr: new Array(),
-                        priority: chart.priority
-                    };
 
-                    families_sort.push(families[family]);
-                }
+                // find the proper family of each alarm
+                var now = Date.now();
+                var x;
+                var count_active = 0;
+                var count_all = 0;
+                var families = {};
+                var families_sort = new Array();
+                for(x in data.alarms) {
+                    var alarm = data.alarms[x];
+                    var family = alarm.family;
+
+                    // find the chart
+                    var chart = options.data.charts[alarm.chart];
+                    if(typeof chart === 'undefined')
+                        chart = options.data.charts_by_name[alarm.chart];
+
+                    // not found - this should never happen!
+                    if(typeof chart === 'undefined') {
+                        console.log('WARNING: alarm ' + x + ' is linked to chart ' + alarm.chart + ', which is not found in the list of chart got from the server.');
+                        chart = { priority: 9999999 };
+                    }
+                    else if(typeof chart.menu !== 'undefined' && typeof chart.submenu !== 'undefined')
+                        // the family based on the chart
+                        family = chart.menu + ' - ' + chart.submenu;
+
+                    if(typeof families[family] === 'undefined') {
+                        families[family] = {
+                            name: family,
+                            arr: new Array(),
+                            priority: chart.priority
+                        };
+
+                        families_sort.push(families[family]);
+                    }
 
-                if(chart.priority < families[family].priority)
-                    families[family].priority = chart.priority;
+                    if(chart.priority < families[family].priority)
+                        families[family].priority = chart.priority;
 
-                families[family].arr.unshift(alarm);
-            }
+                    families[family].arr.unshift(alarm);
+                }
 
-            // sort the families, like the dashboard menu does
-            var families_sorted = families_sort.sort(function (a, b) {
-                if (a.priority > b.priority) return -1;
-                if (a.priority < b.priority) return 1;
-                return 0;
-            });
+                // sort the families, like the dashboard menu does
+                var families_sorted = families_sort.sort(function (a, b) {
+                    if (a.priority > b.priority) return -1;
+                    if (a.priority < b.priority) return 1;
+                    return 0;
+                });
 
-            var fc = 0;
-            var len = families_sorted.length;
-            while(len--) {
-                var family = families_sorted[len].name;
-                var active_family_added = false;
-                var expanded = 'true';
-                var collapsed = '';
-                var cin = 'in';
-
-                if(fc !== 0) {
-                    all += "</table></div></div></div>";
-                    expanded = 'false';
-                    collapsed = 'class="collapsed"'
-                    cin = '';
-                }
+                var fc = 0;
+                var len = families_sorted.length;
+                while(len--) {
+                    var family = families_sorted[len].name;
+                    var active_family_added = false;
+                    var expanded = 'true';
+                    var collapsed = '';
+                    var cin = 'in';
+
+                    if(fc !== 0) {
+                        all += "</table></div></div></div>";
+                        expanded = 'false';
+                        collapsed = 'class="collapsed"'
+                        cin = '';
+                    }
 
-                all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
+                    all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
 
-                options.alarm_families[fc] = families[family];
+                    options.alarm_families[fc] = families[family];
 
-                fc++;
+                    fc++;
 
-                var arr = families[family].arr;
-                var c = arr.length;
-                while(c--) {
-                    var alarm = arr[c];
-                    if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
-                        if(!active_family_added) {
-                            active_family_added = true;
-                            active += '<tr><th class="text-center" colspan="2"><h4>' + family + '</h4></th></tr>';
+                    var arr = families[family].arr;
+                    var c = arr.length;
+                    while(c--) {
+                        var alarm = arr[c];
+                        if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
+                            if(!active_family_added) {
+                                active_family_added = true;
+                                active += '<tr><th class="text-center" colspan="2"><h4>' + family + '</h4></th></tr>';
+                            }
+                            count_active++;
+                            active += alarm_to_html(alarm, true);
                         }
-                        count_active++;
-                        active += alarm_to_html(alarm, true);
-                    }
 
-                    count_all++;
+                        count_all++;
+                    }
                 }
-            }
-            active += "</table>";
-            if(families_sorted.length > 0) all += "</div></div></div>";
-            all += "</div>";
+                active += "</table>";
+                if(families_sorted.length > 0) all += "</div></div></div>";
+                all += "</div>";
 
-            if(!count_active)
-                active += "<h4>Everything is normal. No raised alarms.</h4>";
-            else
-                active += footer;
+                if(!count_active)
+                    active += "<h4>Everything is normal. No raised alarms.</h4>";
+                else
+                    active += footer;
 
-            if(!count_all)
-                all += "<h4>No alarms are running in this system.</h4>";
-            else
-                all += footer;
+                if(!count_all)
+                    all += "<h4>No alarms are running in this system.</h4>";
+                else
+                    all += footer;
 
-            document.getElementById('alarms_active').innerHTML = active;
-            document.getElementById('alarms_all').innerHTML = all;
+                document.getElementById('alarms_active').innerHTML = active;
+                document.getElementById('alarms_all').innerHTML = all;
 
-            if(families_sorted.length > 0) alarm_family_show(0);
+                if(families_sorted.length > 0) alarm_family_show(0);
 
-            // register bootstrap events
-            $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
-                var target = $(d.target);
-                var id = $(target).data('alarm-id');
-                alarm_family_show(id);
-            });
-            $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
-                var target = $(d.target);
-                var id = $(target).data('alarm-id');
-                $('#alarm_all_' + id.toString()).html('');
-            });
+                // register bootstrap events
+                $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
+                    var target = $(d.target);
+                    var id = $(target).data('alarm-id');
+                    alarm_family_show(id);
+                });
+                $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
+                    var target = $(d.target);
+                    var id = $(target).data('alarm-id');
+                    $('#alarm_all_' + id.toString()).html('');
+                });
 
-            document.getElementById('alarms_log').innerHTML = '<h3>Alarm Log</h3><table id="alarms_log_table"></table>';
-
-            loadBootstrapTable(function () {
-                $('#alarms_log_table').bootstrapTable({
-                    url: NETDATA.alarms.server + '/api/v1/alarm_log?all',
-                    cache: false,
-                    pagination: true,
-                    pageSize: 10,
-                    showPaginationSwitch: false,
-                    search: true,
-                    searchTimeOut: 300,
-                    searchAlign: 'left',
-                    showColumns: true,
-                    showExport: true,
-                    exportDataType: 'basic',
-                    exportOptions: {
-                        fileName: 'netdata_alarm_log'
-                    },
-                    rowStyle: function(row, index) {
-                        switch(row.status) {
-                            case 'CRITICAL' : return { classes: 'danger'  }; break;
-                            case 'WARNING'  : return { classes: 'warning' }; break;
-                            case 'UNDEFINED': return { classes: 'info'    }; break;
-                            case 'CLEAR'    : return { classes: 'success' }; break;
-                        }
-                        return {};
-                    },
-                    showFooter: false,
-                    showHeader: true,
-                    showRefresh: true,
-                    showToggle: false,
-                    sortable: true,
-                    silentSort: false,
-                    columns: [
-                        {
-                            field: 'when',
-                            title: 'Event Date',
-                            valign: 'middle',
-                            titleTooltip: 'The date and time the even took place',
-                            formatter: function(value, row, index) { return timestamp4human(value, ' '); },
-                            align: 'center',
-                            valign: 'middle',
-                            switchable: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'hostname',
-                            title: 'Host',
-                            valign: 'middle',
-                            titleTooltip: 'The host that generated this event',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'unique_id',
-                            title: 'Unique ID',
-                            titleTooltip: 'The host unique ID for this event',
-                            formatter: function(value, row, index) { return alarmid4human(value); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
+                document.getElementById('alarms_log').innerHTML = '<h3>Alarm Log</h3><table id="alarms_log_table"></table>';
+
+                loadBootstrapTable(function () {
+                    $('#alarms_log_table').bootstrapTable({
+                        url: NETDATA.alarms.server + '/api/v1/alarm_log?all',
+                        cache: false,
+                        pagination: true,
+                        pageSize: 10,
+                        showPaginationSwitch: false,
+                        search: true,
+                        searchTimeOut: 300,
+                        searchAlign: 'left',
+                        showColumns: true,
+                        showExport: true,
+                        exportDataType: 'basic',
+                        exportOptions: {
+                            fileName: 'netdata_alarm_log'
                         },
-                        {
-                            field: 'alarm_id',
-                            title: 'Alarm ID',
-                            titleTooltip: 'The ID of the alarm that generated this event',
-                            formatter: function(value, row, index) { return alarmid4human(value); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'alarm_event_id',
-                            title: 'Alarm Event ID',
-                            titleTooltip: 'The incremental ID of this event for the given alarm',
-                            formatter: function(value, row, index) { return alarmid4human(value); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'chart',
-                            title: 'Chart',
-                            titleTooltip: 'The chart the alarm is attached to',
-                            align: 'center',
-                            valign: 'middle',
-                            switchable: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'family',
-                            title: 'Family',
-                            titleTooltip: 'The family of the chart the alarm is attached to',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
+                        rowStyle: function(row, index) {
+                            switch(row.status) {
+                                case 'CRITICAL' : return { classes: 'danger'  }; break;
+                                case 'WARNING'  : return { classes: 'warning' }; break;
+                                case 'UNDEFINED': return { classes: 'info'    }; break;
+                                case 'CLEAR'    : return { classes: 'success' }; break;
+                            }
+                            return {};
                         },
-                        {
-                            field: 'name',
-                            title: 'Alarm',
-                            titleTooltip: 'The alarm name that generated this event',
-                            formatter: function(value, row, index) {
-                                return value.toString().replace(/_/g, ' ');
+                        showFooter: false,
+                        showHeader: true,
+                        showRefresh: true,
+                        showToggle: false,
+                        sortable: true,
+                        silentSort: false,
+                        columns: [
+                            {
+                                field: 'when',
+                                title: 'Event Date',
+                                valign: 'middle',
+                                titleTooltip: 'The date and time the even took place',
+                                formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+                                align: 'center',
+                                valign: 'middle',
+                                switchable: false,
+                                sortable: true
                             },
-                            align: 'center',
-                            valign: 'middle',
-                            switchable: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'old_value',
-                            title: 'Old Value',
-                            titleTooltip: 'The value of the alarm, just before this event',
-                            formatter: function(value, row, index) {
-                                return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
+                            {
+                                field: 'hostname',
+                                title: 'Host',
+                                valign: 'middle',
+                                titleTooltip: 'The host that generated this event',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
                             },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'value',
-                            title: 'Value',
-                            titleTooltip: 'The value of the alarm, that triggered this event',
-                            formatter: function(value, row, index) {
-                                return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
+                            {
+                                field: 'unique_id',
+                                title: 'Unique ID',
+                                titleTooltip: 'The host unique ID for this event',
+                                formatter: function(value, row, index) { return alarmid4human(value); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
                             },
-                            align: 'right',
-                            valign: 'middle',
-                            sortable: true
-                        },
-                        {
-                            field: 'units',
-                            title: 'Units',
-                            titleTooltip: 'The units of the value of the alarm',
-                            align: 'left',
-                            valign: 'middle',
-                            sortable: true
-                        },
-                        {
-                            field: 'old_status',
-                            title: 'Old Status',
-                            titleTooltip: 'The status of the alarm, just before this event',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'status',
-                            title: 'Status',
-                            titleTooltip: 'The status of the alarm, that was set due to this event',
-                            align: 'center',
-                            valign: 'middle',
-                            switchable: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'duration',
-                            title: 'Last Duration',
-                            titleTooltip: 'The duration the alarm was at its previous state, just before this event',
-                            formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'non_clear_duration',
-                            title: 'Raised Duration',
-                            titleTooltip: 'The duration the alarm was raised, just before this event',
-                            formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'recipient',
-                            title: 'Recipient',
-                            titleTooltip: 'The recipient of this event',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'processed',
-                            title: 'Processed Status',
-                            titleTooltip: 'True when this event is processed',
-                            formatter: function(value, row, index) {
-                                if(value === true)
-                                    return 'DONE';
-                                else
-                                    return 'PENDING';
+                            {
+                                field: 'alarm_id',
+                                title: 'Alarm ID',
+                                titleTooltip: 'The ID of the alarm that generated this event',
+                                formatter: function(value, row, index) { return alarmid4human(value); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
                             },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'updated',
-                            title: 'Updated Status',
-                            titleTooltip: 'True when this event has been updated by another event',
-                            formatter: function(value, row, index) {
-                                if(value === true)
-                                    return 'UPDATED';
-                                else
-                                    return 'CURRENT';
+                            {
+                                field: 'alarm_event_id',
+                                title: 'Alarm Event ID',
+                                titleTooltip: 'The incremental ID of this event for the given alarm',
+                                formatter: function(value, row, index) { return alarmid4human(value); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
                             },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'updated_by_id',
-                            title: 'Updated By ID',
-                            titleTooltip: 'The unique ID of the event that obsoleted this one',
-                            formatter: function(value, row, index) { return alarmid4human(value); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'updates_id',
-                            title: 'Updates ID',
-                            titleTooltip: 'The unique ID of the event obsoleted because of this event',
-                            formatter: function(value, row, index) { return alarmid4human(value); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'exec',
-                            title: 'Script',
-                            titleTooltip: 'The script to handle the event notification',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'exec_run',
-                            title: 'Script Run At',
-                            titleTooltip: 'The date and time the script has been ran',
-                            formatter: function(value, row, index) { return timestamp4human(value, ' '); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'exec_code',
-                            title: 'Script Return Value',
-                            titleTooltip: 'The return code of the script',
-                            formatter: function(value, row, index) {
-                                if(value === 0)
-                                    return 'OK (returned 0)';
-                                else
-                                    return 'FAILED (with code ' + value.toString() + ')';
+                            {
+                                field: 'chart',
+                                title: 'Chart',
+                                titleTooltip: 'The chart the alarm is attached to',
+                                align: 'center',
+                                valign: 'middle',
+                                switchable: false,
+                                sortable: true
                             },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'delay',
-                            title: 'Script Delay',
-                            titleTooltip: 'The hysteresis of the notification',
-                            formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'delay_up_to_timestamp',
-                            title: 'Script Delay Run At',
-                            titleTooltip: 'The date and time the script should be run, after hysteresis',
-                            formatter: function(value, row, index) { return timestamp4human(value, ' '); },
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'info',
-                            title: 'Description',
-                            titleTooltip: 'A short description of the alarm',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        },
-                        {
-                            field: 'source',
-                            title: 'Alarm Source',
-                            titleTooltip: 'The source of configuration of the alarm',
-                            align: 'center',
-                            valign: 'middle',
-                            visible: false,
-                            sortable: true
-                        }
-                    ]
+                            {
+                                field: 'family',
+                                title: 'Family',
+                                titleTooltip: 'The family of the chart the alarm is attached to',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'name',
+                                title: 'Alarm',
+                                titleTooltip: 'The alarm name that generated this event',
+                                formatter: function(value, row, index) {
+                                    return value.toString().replace(/_/g, ' ');
+                                },
+                                align: 'center',
+                                valign: 'middle',
+                                switchable: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'old_value',
+                                title: 'Old Value',
+                                titleTooltip: 'The value of the alarm, just before this event',
+                                formatter: function(value, row, index) {
+                                    return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
+                                },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'value',
+                                title: 'Value',
+                                titleTooltip: 'The value of the alarm, that triggered this event',
+                                formatter: function(value, row, index) {
+                                    return ((value !== null)?Math.round(value * 100) / 100:'NaN').toString();
+                                },
+                                align: 'right',
+                                valign: 'middle',
+                                sortable: true
+                            },
+                            {
+                                field: 'units',
+                                title: 'Units',
+                                titleTooltip: 'The units of the value of the alarm',
+                                align: 'left',
+                                valign: 'middle',
+                                sortable: true
+                            },
+                            {
+                                field: 'old_status',
+                                title: 'Old Status',
+                                titleTooltip: 'The status of the alarm, just before this event',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'status',
+                                title: 'Status',
+                                titleTooltip: 'The status of the alarm, that was set due to this event',
+                                align: 'center',
+                                valign: 'middle',
+                                switchable: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'duration',
+                                title: 'Last Duration',
+                                titleTooltip: 'The duration the alarm was at its previous state, just before this event',
+                                formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'non_clear_duration',
+                                title: 'Raised Duration',
+                                titleTooltip: 'The duration the alarm was raised, just before this event',
+                                formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'recipient',
+                                title: 'Recipient',
+                                titleTooltip: 'The recipient of this event',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'processed',
+                                title: 'Processed Status',
+                                titleTooltip: 'True when this event is processed',
+                                formatter: function(value, row, index) {
+                                    if(value === true)
+                                        return 'DONE';
+                                    else
+                                        return 'PENDING';
+                                },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'updated',
+                                title: 'Updated Status',
+                                titleTooltip: 'True when this event has been updated by another event',
+                                formatter: function(value, row, index) {
+                                    if(value === true)
+                                        return 'UPDATED';
+                                    else
+                                        return 'CURRENT';
+                                },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'updated_by_id',
+                                title: 'Updated By ID',
+                                titleTooltip: 'The unique ID of the event that obsoleted this one',
+                                formatter: function(value, row, index) { return alarmid4human(value); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'updates_id',
+                                title: 'Updates ID',
+                                titleTooltip: 'The unique ID of the event obsoleted because of this event',
+                                formatter: function(value, row, index) { return alarmid4human(value); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'exec',
+                                title: 'Script',
+                                titleTooltip: 'The script to handle the event notification',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'exec_run',
+                                title: 'Script Run At',
+                                titleTooltip: 'The date and time the script has been ran',
+                                formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'exec_code',
+                                title: 'Script Return Value',
+                                titleTooltip: 'The return code of the script',
+                                formatter: function(value, row, index) {
+                                    if(value === 0)
+                                        return 'OK (returned 0)';
+                                    else
+                                        return 'FAILED (with code ' + value.toString() + ')';
+                                },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'delay',
+                                title: 'Script Delay',
+                                titleTooltip: 'The hysteresis of the notification',
+                                formatter: function(value, row, index) { return seconds4human(value, { negative_suffix: '', space: ' ', now: 'no time' }); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'delay_up_to_timestamp',
+                                title: 'Script Delay Run At',
+                                titleTooltip: 'The date and time the script should be run, after hysteresis',
+                                formatter: function(value, row, index) { return timestamp4human(value, ' '); },
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'info',
+                                title: 'Description',
+                                titleTooltip: 'A short description of the alarm',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            },
+                            {
+                                field: 'source',
+                                title: 'Alarm Source',
+                                titleTooltip: 'The source of configuration of the alarm',
+                                align: 'center',
+                                valign: 'middle',
+                                visible: false,
+                                sortable: true
+                            }
+                        ]
+                    });
+                    // console.log($('#alarms_log_table').bootstrapTable('getOptions'));
                 });
-                // console.log($('#alarms_log_table').bootstrapTable('getOptions'));
             });
-        });
-    }
+        }
+
+        function alarmsCallback(data) {
+            var count = 0;
+            for(x in data.alarms) {
+                var alarm = data.alarms[x];
+                if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
+                    count++;
+            }
 
-    function alarmsCallback(data) {
-        var count = 0;
-        for(x in data.alarms) {
-            var alarm = data.alarms[x];
-            if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
-                count++;
+            if(count > 0)
+                document.getElementById('alarms_count_badge').innerHTML = count.toString();
+            else
+                document.getElementById('alarms_count_badge').innerHTML = '';
         }
 
-        if(count > 0)
-            document.getElementById('alarms_count_badge').innerHTML = count.toString();
-        else
-            document.getElementById('alarms_count_badge').innerHTML = '';
-    }
+        function initializeDynamicDashboard(netdata_url) {
+            if(typeof netdata_url === 'undefined' || netdata_url === null)
+                netdata_url = NETDATA.serverDefault;
+
+            // initialize clickable alarms
+            NETDATA.alarms.chart_div_offset = 100;
+            NETDATA.alarms.chart_div_id_prefix = 'chart_';
+            NETDATA.alarms.chart_div_animation_duration = 0;
+
+            NETDATA.pause(function() {
+                NETDATA.alarms.callback = alarmsCallback;
+
+                // download all the charts the server knows
+                NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
+                    if(data !== null) {
+                        options.hostname = data.hostname;
+                        options.data = data;
+
+                        // update the dashboard hostname
+                        document.getElementById('hostname').innerHTML = options.hostname;
+                        document.getElementById('hostname').href = NETDATA.serverDefault;
+
+                        // update the dashboard title
+                        document.title = options.hostname + ' netdata dashboard';
+
+                        // close the splash screen
+                        $("#loadOverlay").css("display","none");
+
+                        // create a chart_by_name index
+                        data.charts_by_name = {};
+                        var charts = data.charts;
+                        var x;
+                        for(x in charts) {
+                            var chart = charts[x];
+                            data.charts_by_name[chart.name] = chart;
+                        }
 
-    function initializeDynamicDashboard(netdata_url) {
-        if(typeof netdata_url === 'undefined' || netdata_url === null)
-            netdata_url = NETDATA.serverDefault;
-
-        // initialize clickable alarms
-        NETDATA.alarms.chart_div_offset = 100;
-        NETDATA.alarms.chart_div_id_prefix = 'chart_';
-        NETDATA.alarms.chart_div_animation_duration = 0;
-
-        NETDATA.pause(function() {
-            NETDATA.alarms.callback = alarmsCallback;
-
-            // download all the charts the server knows
-            NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
-                if(data !== null) {
-                    options.hostname = data.hostname;
-                    options.data = data;
-
-                    // update the dashboard hostname
-                    document.getElementById('hostname').innerHTML = options.hostname;
-                    document.getElementById('hostname').href = NETDATA.serverDefault;
-
-                    // update the dashboard title
-                    document.title = options.hostname + ' netdata dashboard';
-
-                    // close the splash screen
-                    $("#loadOverlay").css("display","none");
-
-                    // create a chart_by_name index
-                    data.charts_by_name = {};
-                    var charts = data.charts;
-                    var x;
-                    for(x in charts) {
-                        var chart = charts[x];
-                        data.charts_by_name[chart.name] = chart;
+                        // render all charts
+                        renderChartsAndMenu(data);
                     }
-
-                    // render all charts
-                    renderChartsAndMenu(data);
-                }
+                });
             });
-        });
-    }
+        }
 
-    // ----------------------------------------------------------------------------
+        // ----------------------------------------------------------------------------
 
-    function versionLog(msg) {
-        document.getElementById('versionCheckLog').innerHTML = msg;
-    }
+        function versionLog(msg) {
+            document.getElementById('versionCheckLog').innerHTML = msg;
+        }
 
-    function getNetdataVersion(callback) {
-        versionLog('Downloading installed version info from netdata...');
-
-        $.ajax({
-            url: 'version.txt',
-            async: true,
-            cache: false,
-            xhrFields: { withCredentials: true } // required for the cookie
-        })
-        .done(function(data) {
-            data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
-            if(data.length !== 40) {
-                versionLog('Received version string is invalid.');
+        function getNetdataVersion(callback) {
+            versionLog('Downloading installed version info from netdata...');
+
+            $.ajax({
+                url: 'version.txt',
+                async: true,
+                cache: false,
+                xhrFields: { withCredentials: true } // required for the cookie
+            })
+            .done(function(data) {
+                data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
+                if(data.length !== 40) {
+                    versionLog('Received version string is invalid.');
+                    callback(null);
+                }
+                else {
+                    versionLog('Installed version of netdata is ' + data);
+                    document.getElementById('netdataVersion').innerHTML = data;
+                    callback(data);
+                }
+            })
+            .fail(function() {
+                versionLog('Failed to download installed version info from netdata!');
                 callback(null);
-            }
-            else {
-                versionLog('Installed version of netdata is ' + data);
-                document.getElementById('netdataVersion').innerHTML = data;
-                callback(data);
-            }
-        })
-        .fail(function() {
-            versionLog('Failed to download installed version info from netdata!');
-            callback(null);
-        });
-    }
-
-    function getGithubLatestCommit(callback) {
-        versionLog('Downloading latest version info from github...');
-
-        $.ajax({
-            url: 'https://api.github.com/repos/firehol/netdata/commits',
-            async: true,
-            cache: false
-        })
-        .done(function(data) {
-            versionLog('Latest version info from github is ' + data[0].sha);
-            callback(data[0].sha);
-        })
-        .fail(function() {
-            versionLog('Failed to download installed version info from github!');
-            callback(null);
-        });
-    }
-
-    function checkForUpdate(callback) {
-        getNetdataVersion(function(sha1) {
-            if(sha1 === null) callback(null, null);
+            });
+        }
 
-            getGithubLatestCommit(function(sha2) {
-                callback(sha1, sha2);
+        function getGithubLatestCommit(callback) {
+            versionLog('Downloading latest version info from github...');
+
+            $.ajax({
+                url: 'https://api.github.com/repos/firehol/netdata/commits',
+                async: true,
+                cache: false
+            })
+            .done(function(data) {
+                versionLog('Latest version info from github is ' + data[0].sha);
+                callback(data[0].sha);
+            })
+            .fail(function() {
+                versionLog('Failed to download installed version info from github!');
+                callback(null);
             });
-        });
+        }
 
-        return null;
-    }
+        function checkForUpdate(callback) {
+            getNetdataVersion(function(sha1) {
+                if(sha1 === null) callback(null, null);
 
-    function notifyForUpdate(force) {
-        versionLog('<p>checking for updates...</p>');
+                getGithubLatestCommit(function(sha2) {
+                    callback(sha1, sha2);
+                });
+            });
 
-        var now = Date.now();
+            return null;
+        }
 
-        if(typeof force === 'undefined' || force !== true) {
-            var last = loadLocalStorage('last_update_check');
+        function notifyForUpdate(force) {
+            versionLog('<p>checking for updates...</p>');
 
-            if(typeof last === 'string')
-                last = parseInt(last);
-            else
-                last = 0;
+            var now = Date.now();
 
-            if(now - last < 3600000 * 8) {
-                // no need to check it - too soon
-                return;
-            }
-        }
+            if(typeof force === 'undefined' || force !== true) {
+                var last = loadLocalStorage('last_update_check');
 
-        checkForUpdate(function(sha1, sha2) {
-            var save = false;
+                if(typeof last === 'string')
+                    last = parseInt(last);
+                else
+                    last = 0;
 
-            if(sha1 === null) {
-                save = false;
-                versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
-            }
-            else if(sha2 === null) {
-                save = false;
-                versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
-            }
-            else if(sha1 === sha2) {
-                save = true;
-                versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
+                if(now - last < 3600000 * 8) {
+                    // no need to check it - too soon
+                    return;
+                }
             }
-            else {
-                save = true;
-                var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
 
-                versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
-
-                document.getElementById('update_badge').innerHTML = '!';
-            }
+            checkForUpdate(function(sha1, sha2) {
+                var save = false;
 
-            if(save)
-                saveLocalStorage('last_update_check', now.toString());
-        });
-    }
+                if(sha1 === null) {
+                    save = false;
+                    versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
+                }
+                else if(sha2 === null) {
+                    save = false;
+                    versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
+                }
+                else if(sha1 === sha2) {
+                    save = true;
+                    versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
+                }
+                else {
+                    save = true;
+                    var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
 
-    // ----------------------------------------------------------------------------
-
-    function finalizePage() {
-        // resize all charts - without starting the background thread
-        // this has to be done while NETDATA is paused
-        // if we ommit this, the affix menu will be wrong, since all
-        // the Dom elements are initially zero-sized
-        NETDATA.parseDom();
-
-        if(urlOptions.pan_and_zoom === true)
-            NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
-
-        // ------------------------------------------------------------------------
-        // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
-        $.fn.shorten = function(settings) {
-            "use strict";
-
-            var config = {
-                showChars: 750,
-                minHideChars: 10,
-                ellipsesText: "...",
-                moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
-                lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
-                onLess: function() { NETDATA.onscroll(); },
-                onMore: function() { NETDATA.onscroll(); },
-                errMsg: null,
-                force: false
-            };
+                    versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
 
-            if (settings) {
-                $.extend(config, settings);
-            }
+                    document.getElementById('update_badge').innerHTML = '!';
+                }
 
-            if ($(this).data('jquery.shorten') && !config.force) {
-                return false;
-            }
-            $(this).data('jquery.shorten', true);
+                if(save)
+                    saveLocalStorage('last_update_check', now.toString());
+            });
+        }
 
-            $(document).off("click", '.morelink');
+        // ----------------------------------------------------------------------------
+
+        function finalizePage() {
+            // resize all charts - without starting the background thread
+            // this has to be done while NETDATA is paused
+            // if we ommit this, the affix menu will be wrong, since all
+            // the Dom elements are initially zero-sized
+            NETDATA.parseDom();
+
+            if(urlOptions.pan_and_zoom === true)
+                NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
+
+            // ------------------------------------------------------------------------
+            // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
+            $.fn.shorten = function(settings) {
+                "use strict";
+
+                var config = {
+                    showChars: 750,
+                    minHideChars: 10,
+                    ellipsesText: "...",
+                    moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
+                    lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
+                    onLess: function() { NETDATA.onscroll(); },
+                    onMore: function() { NETDATA.onscroll(); },
+                    errMsg: null,
+                    force: false
+                };
 
-            $(document).on({
-                click: function() {
+                if (settings) {
+                    $.extend(config, settings);
+                }
 
-                    var $this = $(this);
-                    if ($this.hasClass('less')) {
-                        $this.removeClass('less');
-                        $this.html(config.moreText);
-                        $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
-                            config.onLess();
-                        });
-
-                    } else {
-                        $this.addClass('less');
-                        $this.html(config.lessText);
-                        $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
-                            config.onMore();
-                        });
-                    }
+                if ($(this).data('jquery.shorten') && !config.force) {
                     return false;
                 }
-            }, '.morelink');
+                $(this).data('jquery.shorten', true);
+
+                $(document).off("click", '.morelink');
+
+                $(document).on({
+                    click: function() {
+
+                        var $this = $(this);
+                        if ($this.hasClass('less')) {
+                            $this.removeClass('less');
+                            $this.html(config.moreText);
+                            $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
+                                config.onLess();
+                            });
+
+                        } else {
+                            $this.addClass('less');
+                            $this.html(config.lessText);
+                            $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
+                                config.onMore();
+                            });
+                        }
+                        return false;
+                    }
+                }, '.morelink');
 
-            return this.each(function() {
-                var $this = $(this);
+                return this.each(function() {
+                    var $this = $(this);
 
-                var content = $this.html();
-                var contentlen = $this.text().length;
-                if (contentlen > config.showChars + config.minHideChars) {
-                    var c = content.substr(0, config.showChars);
-                    if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
-                    {
-                        var inTag = false; // I'm in a tag?
-                        var bag = ''; // Put the characters to be shown here
-                        var countChars = 0; // Current bag size
-                        var openTags = []; // Stack for opened tags, so I can close them later
-                        var tagName = null;
+                    var content = $this.html();
+                    var contentlen = $this.text().length;
+                    if (contentlen > config.showChars + config.minHideChars) {
+                        var c = content.substr(0, config.showChars);
+                        if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
+                        {
+                            var inTag = false; // I'm in a tag?
+                            var bag = ''; // Put the characters to be shown here
+                            var countChars = 0; // Current bag size
+                            var openTags = []; // Stack for opened tags, so I can close them later
+                            var tagName = null;
 
-                        for (var i = 0, r = 0; r <= config.showChars; i++) {
-                            if (content[i] == '<' && !inTag) {
-                                inTag = true;
+                            for (var i = 0, r = 0; r <= config.showChars; i++) {
+                                if (content[i] == '<' && !inTag) {
+                                    inTag = true;
 
-                                // This could be "tag" or "/tag"
-                                tagName = content.substring(i + 1, content.indexOf('>', i));
+                                    // This could be "tag" or "/tag"
+                                    tagName = content.substring(i + 1, content.indexOf('>', i));
 
-                                // If its a closing tag
-                                if (tagName[0] == '/') {
+                                    // If its a closing tag
+                                    if (tagName[0] == '/') {
 
 
-                                    if (tagName != '/' + openTags[0]) {
-                                        config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
-                                    } else {
-                                        openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
-                                    }
+                                        if (tagName != '/' + openTags[0]) {
+                                            config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
+                                        } else {
+                                            openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
+                                        }
 
-                                } else {
-                                    // There are some nasty tags that don't have a close tag like <br/>
-                                    if (tagName.toLowerCase() != 'br') {
-                                        openTags.unshift(tagName); // Add to start the name of the tag that opens
+                                    } else {
+                                        // There are some nasty tags that don't have a close tag like <br/>
+                                        if (tagName.toLowerCase() != 'br') {
+                                            openTags.unshift(tagName); // Add to start the name of the tag that opens
+                                        }
                                     }
                                 }
-                            }
-                            if (inTag && content[i] == '>') {
-                                inTag = false;
-                            }
+                                if (inTag && content[i] == '>') {
+                                    inTag = false;
+                                }
 
-                            if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
-                            else {
-                                r++;
-                                if (countChars <= config.showChars) {
-                                    bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
-                                    countChars++;
-                                } else // Now I have the characters needed
-                                {
-                                    if (openTags.length > 0) // I have unclosed tags
+                                if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
+                                else {
+                                    r++;
+                                    if (countChars <= config.showChars) {
+                                        bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
+                                        countChars++;
+                                    } else // Now I have the characters needed
                                     {
-                                        //console.log('They were open tags');
-                                        //console.log(openTags);
-                                        for (j = 0; j < openTags.length; j++) {
-                                            //console.log('Cierro tag ' + openTags[j]);
-                                            bag += '</' + openTags[j] + '>'; // Close all tags that were opened
-
-                                            // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags
+                                        if (openTags.length > 0) // I have unclosed tags
+                                        {
+                                            //console.log('They were open tags');
+                                            //console.log(openTags);
+                                            for (j = 0; j < openTags.length; j++) {
+                                                //console.log('Cierro tag ' + openTags[j]);
+                                                bag += '</' + openTags[j] + '>'; // Close all tags that were opened
+
+                                                // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags
+                                            }
+                                            break;
                                         }
-                                        break;
                                     }
                                 }
                             }
+                            c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
+                        }else{
+                            c+=config.ellipsesText;
                         }
-                        c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
-                    }else{
-                        c+=config.ellipsesText;
+
+                        var html = '<div class="shortcontent">' + c +
+                                '</div><div class="allcontent">' + content +
+                                '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
+
+                        $this.html(html);
+                        $this.find(".allcontent").hide(); // Hide all text
+                        $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
                     }
+                });
+
+            };
+            $(".chart-message").shorten();
+            // ------------------------------------------------------------------------
+
+            // callback for us to track PanAndZoom operations
+            NETDATA.globalPanAndZoom.callback = urlOptions.netdataPanAndZoomCallback;
+
+            // let it run (update the charts)
+            NETDATA.unpause();
+
+            // check if we have to jump to a specific section
+            scrollToId(urlOptions.hash.replace('#',''));
 
-                    var html = '<div class="shortcontent">' + c +
-                            '</div><div class="allcontent">' + content +
-                            '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
+            if(urlOptions.chart !== null) {
+                NETDATA.alarms.scrollToChart(urlOptions.chart);
+                //urlOptions.hash = '#' + NETDATA.name2id('menu_' + charts[c].menu + '_submenu_' + charts[c].submenu);
+                //urlOptions.hash = '#chart_' + NETDATA.name2id(urlOptions.chart);
+                //console.log('hash = ' + urlOptions.hash);
+            }
 
-                    $this.html(html);
-                    $this.find(".allcontent").hide(); // Hide all text
-                    $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
+            /* activate bootstrap sidebar (affix) */
+            $('#sidebar').affix({
+                offset: {
+                    top: (isdemo())?150:0,
+                    bottom: 0
                 }
             });
 
-        };
-        $(".chart-message").shorten();
-        // ------------------------------------------------------------------------
-
-        // callback for us to track PanAndZoom operations
-        NETDATA.globalPanAndZoom.callback = urlOptions.netdataPanAndZoomCallback;
+            /* fix scrolling of very long affix lists
+               http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
+             */
+            $('#sidebar').on('affixed.bs.affix', function() {
+                $(this).removeAttr('style');
+            });
 
-        // let it run (update the charts)
-        NETDATA.unpause();
+            /* activate bootstrap scrollspy (needed for sidebar) */
+            $(document.body).scrollspy({
+                target: '#sidebar',
+                offset: $(window).height() / 5 // controls the diff of the <hX> element to the top, to select it
+            });
 
-        // check if we have to jump to a specific section
-        scrollToId(urlOptions.hash.replace('#',''));
+            // change the URL based on the current position of the screen
+            $('#sidebar').on('activate.bs.scrollspy', function (e) {
+                // console.log(e);
+                var el = $(e.target);
+                //if(el.find('ul').size() == 0) {
+                var hash = el.find('a').attr('href');
+                if(typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) {
+                    urlOptions.hash = hash;
+                    //console.log(urlOptions.hash);
+                    urlOptions.hashUpdate();
+                }
+                //else console.log('hash: not accepting ' + hash);
+                //}
+                //else console.log('el.find(): not found');
+            });
 
-        if(urlOptions.chart !== null) {
-            NETDATA.alarms.scrollToChart(urlOptions.chart);
-            //urlOptions.hash = '#' + NETDATA.name2id('menu_' + charts[c].menu + '_submenu_' + charts[c].submenu);
-            //urlOptions.hash = '#chart_' + NETDATA.name2id(urlOptions.chart);
-            //console.log('hash = ' + urlOptions.hash);
-        }
+            document.getElementById('footer').style.display = 'block';
 
-        /* activate bootstrap sidebar (affix) */
-        $('#sidebar').affix({
-            offset: {
-                top: (isdemo())?150:0,
-                bottom: 0
-            }
-        });
-
-        /* fix scrolling of very long affix lists
-           http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
-         */
-        $('#sidebar').on('affixed.bs.affix', function() {
-            $(this).removeAttr('style');
-        });
-
-        /* activate bootstrap scrollspy (needed for sidebar) */
-        $(document.body).scrollspy({
-            target: '#sidebar',
-            offset: $(window).height() / 5 // controls the diff of the <hX> element to the top, to select it
-        });
-
-        // change the URL based on the current position of the screen
-        $('#sidebar').on('activate.bs.scrollspy', function (e) {
-            // console.log(e);
-            var el = $(e.target);
-            //if(el.find('ul').size() == 0) {
-            var hash = el.find('a').attr('href');
-            if(typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) {
-                urlOptions.hash = hash;
-                //console.log(urlOptions.hash);
-                urlOptions.hashUpdate();
-            }
-            //else console.log('hash: not accepting ' + hash);
-            //}
-            //else console.log('el.find(): not found');
-        });
+            var update_options_modal = function() {
+                // console.log('update_options_modal');
 
-        document.getElementById('footer').style.display = 'block';
+                var sync_option = function(option) {
+                    var self = $('#' + option);
 
-        var update_options_modal = function() {
-            // console.log('update_options_modal');
+                    if(self.prop('checked') !== NETDATA.getOption(option)) {
+                        // console.log('switching ' + option.toString());
+                        self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
+                    }
+                }
 
-            var sync_option = function(option) {
-                var self = $('#' + option);
+                var theme_sync_option = function(option) {
+                    var self = $('#' + option);
 
-                if(self.prop('checked') !== NETDATA.getOption(option)) {
-                    // console.log('switching ' + option.toString());
-                    self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
+                    self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
                 }
-            }
 
-            var theme_sync_option = function(option) {
-                var self = $('#' + option);
+                sync_option('eliminate_zero_dimensions');
+                sync_option('destroy_on_hide');
+                sync_option('async_on_scroll');
+                sync_option('parallel_refresher');
+                sync_option('concurrent_refreshes');
+                sync_option('sync_selection');
+                sync_option('sync_pan_and_zoom');
+                sync_option('stop_updates_when_focus_is_lost');
+                sync_option('smooth_plot');
+                sync_option('pan_and_zoom_data_padding');
+                sync_option('show_help');
+                theme_sync_option('netdata_theme_control');
+
+                if(NETDATA.getOption('parallel_refresher') === false) {
+                    $('#concurrent_refreshes_row').hide();
+                }
+                else {
+                    $('#concurrent_refreshes_row').show();
+                }
+            };
+            NETDATA.setOption('setOptionCallback', update_options_modal);
+
+            // handle options changes
+            $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
+            $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
+            $('#async_on_scroll').change(function()                 { NETDATA.setOption('async_on_scroll', $(this).prop('checked')); });
+            $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
+            $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
+            $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
+            $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
+            $('#stop_updates_when_focus_is_lost').change(function() {
+                urlOptions.update_always = !$(this).prop('checked');
+                urlOptions.hashUpdate();
 
-                self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
-            }
+                NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always);
+            });
+            $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
+            $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
+            $('#show_help').change(function()                       {
+                urlOptions.help = $(this).prop('checked');
+                urlOptions.hashUpdate();
 
-            sync_option('eliminate_zero_dimensions');
-            sync_option('destroy_on_hide');
-            sync_option('async_on_scroll');
-            sync_option('parallel_refresher');
-            sync_option('concurrent_refreshes');
-            sync_option('sync_selection');
-            sync_option('sync_pan_and_zoom');
-            sync_option('stop_updates_when_focus_is_lost');
-            sync_option('smooth_plot');
-            sync_option('pan_and_zoom_data_padding');
-            sync_option('show_help');
-            theme_sync_option('netdata_theme_control');
-
-            if(NETDATA.getOption('parallel_refresher') === false) {
-                $('#concurrent_refreshes_row').hide();
-            }
-            else {
-                $('#concurrent_refreshes_row').show();
-            }
-        };
-        NETDATA.setOption('setOptionCallback', update_options_modal);
-
-        // handle options changes
-        $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
-        $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
-        $('#async_on_scroll').change(function()                 { NETDATA.setOption('async_on_scroll', $(this).prop('checked')); });
-        $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
-        $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
-        $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
-        $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
-        $('#stop_updates_when_focus_is_lost').change(function() {
-            urlOptions.update_always = !$(this).prop('checked');
-            urlOptions.hashUpdate();
-
-            NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always);
-        });
-        $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
-        $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
-        $('#show_help').change(function()                       {
-            urlOptions.help = $(this).prop('checked');
-            urlOptions.hashUpdate();
-
-            NETDATA.setOption('show_help', urlOptions.help);
-            netdataReload();
-        });
-
-        // this has to be the last
-        // it reloads the page
-        $('#netdata_theme_control').change(function() {
-            urlOptions.theme = $(this).prop('checked')?'slate':'white';
-            urlOptions.hashUpdate();
-
-            if(setTheme(urlOptions.theme))
+                NETDATA.setOption('show_help', urlOptions.help);
                 netdataReload();
-        });
+            });
+
+            // this has to be the last
+            // it reloads the page
+            $('#netdata_theme_control').change(function() {
+                urlOptions.theme = $(this).prop('checked')?'slate':'white';
+                urlOptions.hashUpdate();
 
-        $('#updateModal').on('shown.bs.modal', function() {
-            notifyForUpdate(true);
-        });
+                if(setTheme(urlOptions.theme))
+                    netdataReload();
+            });
 
-        $('#alarmsModal').on('shown.bs.modal', function() {
-            NETDATA.pause(alarmsUpdateModal);
-        });
+            $('#updateModal').on('show.bs.modal', function() {
+                versionLog('checking, please wait...');
+            });
 
-        $('#alarmsModal').on('hidden.bs.modal', function() {
-            NETDATA.unpause();
-            document.getElementById('alarms_active').innerHTML =
-                    document.getElementById('alarms_all').innerHTML =
-                    document.getElementById('alarms_log').innerHTML =
-                            'loading...';
-        });
-
-        $('#deleteRegistryModal').on('hidden.bs.modal', function() {
-            deleteRegistryGuid = null;
-        });
-
-        if(isdemo()) {
-            if(urlOptions.nowelcome !== true) {
+            $('#updateModal').on('shown.bs.modal', function() {
+                notifyForUpdate(true);
+            });
+
+            $('#alarmsModal').on('shown.bs.modal', function() {
+                NETDATA.pause(alarmsUpdateModal);
+            });
+
+            $('#alarmsModal').on('hidden.bs.modal', function() {
+                NETDATA.unpause();
+                document.getElementById('alarms_active').innerHTML =
+                        document.getElementById('alarms_all').innerHTML =
+                        document.getElementById('alarms_log').innerHTML =
+                                'loading...';
+            });
+
+            $('#deleteRegistryModal').on('hidden.bs.modal', function() {
+                deleteRegistryGuid = null;
+            });
+
+            if(isdemo()) {
+                // do not to give errors on netdata demo servers for 60 seconds
+                NETDATA.options.current.retries_on_data_failures = 60;
+
+                if(urlOptions.nowelcome !== true) {
+                    setTimeout(function() {
+                        $('#welcomeModal').modal();
+                    }, 1000);
+                }
+
+                // google analytics when this is used for the home page of the demo sites
+                // this does not run on user's installations
                 setTimeout(function() {
-                    $('#welcomeModal').modal();
-                }, 1000);
+                    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+                    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+                    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+                    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+                    ga('create', 'UA-64295674-3', 'auto');
+                    ga('send', 'pageview');
+                }, 2000);
             }
+            else notifyForUpdate();
+
+            if(urlOptions.show_alarms === true)
+                setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000);
+
+            var sidebar = document.getElementById('sidebar');
+            Ps.initialize(sidebar, {
+                wheelSpeed: 0.5,
+                wheelPropagation: true,
+                swipePropagation: true,
+                minScrollbarLength: null,
+                maxScrollbarLength: null,
+                useBothWheelAxes: false,
+                suppressScrollX: true,
+                suppressScrollY: false,
+                scrollXMarginOffset: 0,
+                scrollYMarginOffset: 0,
+                theme: 'default'
+            });
+            Ps.update(sidebar);
+
+            var registry = document.getElementById('myNetdataDropdownUL');
+            Ps.initialize(registry, {
+                wheelSpeed: 1,
+                wheelPropagation: false,
+                swipePropagation: false,
+                minScrollbarLength: null,
+                maxScrollbarLength: null,
+                useBothWheelAxes: false,
+                suppressScrollX: true,
+                suppressScrollY: false,
+                scrollXMarginOffset: 0,
+                scrollYMarginOffset: 0,
+                theme: 'default'
+            });
+            Ps.update(registry);
 
-            // google analytics when this is used for the home page of the demo sites
-            // this does not run on user's installations
-            setTimeout(function() {
-                (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
-                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
-                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
-                })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+            NETDATA.onresizeCallback = function() {
+                Ps.update(sidebar);
+                Ps.update(registry);
+            };
 
-                ga('create', 'UA-64295674-3', 'auto');
-                ga('send', 'pageview');
-            }, 2000);
+            $('#myNetdataDropdownParent')
+                .on('show.bs.dropdown', function () {
+                    NETDATA.pause(function() {});
+                })
+                .on('shown.bs.dropdown', function () {
+                    Ps.update(registry);
+                })
+                .on('hidden.bs.dropdown', function () {
+                    NETDATA.unpause();
+                });
+
+            // var netdataEnded = performance.now();
+            // console.log('start up time: ' + (netdataEnded - netdataStarted).toString() + ' ms');
         }
-        else notifyForUpdate();
 
-        if(urlOptions.show_alarms === true)
-            setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000);
-    }
+        function resetDashboardOptions() {
+            var help = NETDATA.options.current.show_help;
 
-    function resetDashboardOptions() {
-        var help = NETDATA.options.current.show_help;
+            NETDATA.resetOptions();
+            if(setTheme('slate'))
+                netdataReload();
 
-        NETDATA.resetOptions();
-        if(setTheme('slate'))
-            netdataReload();
+            if(help !== NETDATA.options.current.show_help)
+                netdataReload();
+        }
 
-        if(help !== NETDATA.options.current.show_help)
-            netdataReload();
-    }
+        // callback to add the dashboard info to the
+        // parallel javascript downloader in netdata
+        var netdataPrepCallback = function() {
+            NETDATA.requiredCSS.push({
+                url: NETDATA.serverDefault + 'css/bootstrap-toggle-2.2.2.min.css',
+                isAlreadyLoaded: function() { return false; }
+            });
 
-    // callback to add the dashboard info to the
-    // parallel javascript downloader in netdata
-    var netdataPrepCallback = function() {
-        NETDATA.requiredCSS.push({
-            url: NETDATA.serverDefault + 'css/bootstrap-toggle-2.2.2.min.css',
-            isAlreadyLoaded: function() { return false; }
-        });
-
-        NETDATA.requiredJs.push({
-            url: NETDATA.serverDefault + 'lib/bootstrap-toggle-2.2.2.min.js',
-            isAlreadyLoaded: function() { return false; }
-        });
-
-        NETDATA.requiredJs.push({
-            url: NETDATA.serverDefault + 'dashboard_info.js?v20161112-6',
-            async: false,
-            isAlreadyLoaded: function() { return false; }
-        });
-
-        if(isdemo()) {
-            document.getElementById('masthead').style.display = 'block';
-        }
-        else {
-            if(urlOptions.update_always === true)
-                NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always);
-        }
-    }
+            NETDATA.requiredJs.push({
+                url: NETDATA.serverDefault + 'lib/bootstrap-toggle-2.2.2.min.js',
+                isAlreadyLoaded: function() { return false; }
+            });
+
+            NETDATA.requiredJs.push({
+                url: NETDATA.serverDefault + 'dashboard_info.js?v20170115-1',
+                async: false,
+                isAlreadyLoaded: function() { return false; }
+            });
 
-    // our entry point
-    var netdataCallback = initializeDynamicDashboard;
+            if(isdemo()) {
+                document.getElementById('masthead').style.display = 'block';
+            }
+            else {
+                if(urlOptions.update_always === true)
+                    NETDATA.setOption('stop_updates_when_focus_is_lost', !urlOptions.update_always);
+            }
+        };
 
-</script>
+        // our entry point
+        // var netdataStarted = performance.now();
+        var netdataCallback = initializeDynamicDashboard;
+    </script>
+</head>
 
 <body data-spy="scroll" data-target="#sidebar">
     <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
         <div class="container">
             <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
                 <ul class="nav navbar-nav">
-                    <li class="dropdown">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
-                        <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
+                    <li class="dropdown" id="myNetdataDropdownParent">
+                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a>
+                        <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu" id="myNetdataDropdownUL">
                             <div class="row">
                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
                                     <ul id="mynetdata_servers" class="multi-column-dropdown">
             </div>
             <nav class="collapse navbar-collapse navbar-right" role="navigation">
                 <ul class="nav navbar-nav">
-                    <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i></span>&nbsp;<span class="hidden-sm">Alarms&nbsp;</span><span id="alarms_count_badge" class="badge"></a></li>
+                    <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i>&nbsp;<span class="hidden-sm">Alarms&nbsp;</span><span id="alarms_count_badge" class="badge"></span></a></li>
                     <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i>&nbsp;<span class="hidden-sm">Settings</span></a></li>
-                    <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata community"><i class="fa fa-github"></i>&nbsp;<span class="hidden-sm hidden-md">Community</span></a></li>
-                    <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i><span id="update_badge" class="badge"></span>&nbsp;<span class="hidden-sm hidden-md">Update</span></a></li>
+                    <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i> <span class="hidden-sm hidden-md">Update </span><span id="update_badge" class="badge"></span></a></li>
+                    <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata on github"><i class="fa fa-github"></i></a></li>
+                    <li><a href="https://twitter.com/linuxnetdata" class="btn" target="_blank" title="netdata on twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a></li>
+                    <li><a href="https://www.facebook.com/linuxnetdata/" class="btn" target="_blank" title="netdata on facebook"><i class="fa fa-facebook-official" aria-hidden="true"></i></a></li>
                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i>&nbsp;<span class="hidden-sm hidden-md">Help</span></a></li>
-                    <!--
-                    <li class="dropdown hidden-md hidden-lg hidden-xs">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
-                        <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fa fa-bell"></i> alarms</a></li>
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-sliders"></i> settings</a></li>
-                            <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
-                            <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
-                        </ul>
-                    </li>
-                    -->
                     <li class="dropdown hidden-sm hidden-md hidden-lg">
-                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
+                        <a href="#" class="dropdown-toggle" data-toggle="dropdown">my-netdata <strong class="caret"></strong></a>
                         <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
                             <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
                         </ul>
                     </li>
                 </ul>
             </nav>
-    </nav>
         </div>
     </nav>
 
             <div class="charts-body" role="main">
                 <div id="charts_div"></div>
             </div>
-            <div class="sidebar-body hidden-xs hidden-sm" role="complementary">
+            <div class="sidebar-body hidden-xs hidden-sm" id="sidebar-body" role="complementary">
                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
             </div>
         </div>
             <div class="col-md-10" role="main">
                 <div class="p">
                     <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
-                    <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
+                    <i class="fa fa-copyright"></i> Copyright 2016-2017, <a href="mailto:costa@tsaousis.gr">Costa Tsaousis</a>.<br/>
                     Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
                 </div>
                 <div class="p">
                         <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
                         <i class="fa fa-copyright"></i> Copyright (c) 2011-2014 Min Hur, The New York Times Company, <a href="https://github.com/minhur/bootstrap-toggle/blob/master/LICENSE" target="_blank">MIT License</a>
 
-                        <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
-                        <i class="fa fa-copyright"></i> Copyright 2012, James Florentino, <a href="https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE" target="_blank">MIT License</a>
+                        <i class="fa fa-circle"></i> <a href="https://github.com/noraesae/perfect-scrollbar" target="_blank">perfect-scrollbar</a>,
+                        <i class="fa fa-copyright"></i> Copyright 2016, Hyunje Alex Jun and other contributors, <a href="https://github.com/noraesae/perfect-scrollbar/blob/master/LICENSE" target="_blank">MIT License</a>
 
                         <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
                         <i class="fa fa-copyright"></i> Created by Dave Gandy, Font: <a href="http://scripts.sil.org/OFL" target="_blank">SIL OFL 1.1 License</a>, CSS: <a href="http://opensource.org/licenses/mit-license.html" target="_blank">MIT License</a>
             <div class="modal-content">
                 <div class="modal-header">
                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
-                    <h4 class="modal-title" id="welcomeModalLabel">Welcome</h4>
+                    <h4 class="modal-title" id="welcomeModalLabel">Welcome to the world of netdata</h4>
                 </div>
                 <div class="modal-body">
                     <div class="p">
-                        You found <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> !
+                        <div style="width: 100%; text-align: center; padding-top: 10px; padding-bottom: 10px; font-size: 18px;">
+                            if there is a metric for something, we want it visualised<br/>
+                            and we want this visualisation to be <strong>real-time</strong>, <strong>efficient</strong> and <strong>awesome</strong>
+                        </div>
                     </div>
                     <div class="p">
                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>
-                        is the best way to monitor your servers and applications, to get <strong>real-time insights</strong>
+                        is a new way to monitor your systems and applications, to get <strong>real-time insights</strong>
                         of what is really happening and what affects performance.
+                        It is carefully optimised to be a real-time system, without interfering in any way,
+                        to the core function of your systems.
                     </div>
                     <div class="p">
-                        This page is a live demo of it.
-                    </div>
-                    <hr/>
-                    <div class="p">
-                        <h4>it is ok to always run <strong>netdata</strong></h4>
-                        We have carefully optimised
                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>
-                        to achieve a real-time performance monitoring solution that does not interfere, in any way,
-                        to the core function of your servers or devices:
-                        <br/>&nbsp;<br/>
-                        <ul>
-                            <li>most installations will use just 1% cpu utilization of a single core and a few MB of RAM.</li>
-                            <li>it runs with the <code>SCHED_IDLE</code> process scheduler
-                                (check <code>man 2 sched_setscheduler</code>), for <i>very</i> low priority, lower than <code>nice 19</code>.</li>
-                            <li>it adjusts its Out-Of-Memory score (OOM) to the maximum, so that it will be the first process
-                                to be killed if your system starves for memory.</li>
-                        </ul>
-                    </div>
-                    <hr/>
-                    <div class="p">
-                        <h4>more metrics is good</h4>
-                        We designed <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>
-                        to monitor <strong>massive amounts of metrics, per server, per second</strong>.
-                        When installed on your systems it might come up with 1k or 2k metrics, but we have tested it with 100k
+                        has been designed to monitor <strong>massive amounts of metrics, per server, per second</strong>.
+                        When installed, it might come up with 1k to 3k metrics, but we have been testing it with 100k
                         metrics, all collected per second, and still the cpu utilisation remained negligible.
-                        <div style="width: 100%; text-align: center; padding-top: 10px; padding-bottom: 10px; font-size: 16px;">
-                            if there is a metric for something, we want it visualised<br/>
-                            and we want this visualisation to be <strong>real-time</strong>, <strong>efficient</strong> and <strong>awesome</strong>
-                        </div>
-                        We have also tried to give a meaning to each metric - to be educational.
-                        We have grouped, categorized and classified metrics into meaningful charts, providing the leads for
-                        better understanding the underlying technologies and mechanisms.
+                        <br/>
+                        We have also tried to give each metric, a meaning, a context.
+                        We have grouped and categorized all metrics into meaningful charts, providing a
+                        better understanding of the underlying technologies and mechanisms.
                     </div>
-                    <hr/>
                     <div class="p">
-                        <h4><b><a href="https://github.com/firehol/netdata/wiki/a-github-star-is-important" target="_blank">a GitHub star is important</a></b></h4>
                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> is free,
-                        open-source software. If you like it, you should
-                        <a href="https://github.com/firehol/netdata/wiki/a-github-star-is-important" target="_blank">give netdata a star at GitHub</a>.
+                        open-source software. If you decide to use it,
+                        <strong><a href="https://github.com/firehol/netdata/wiki/a-github-star-is-important" target="_blank">it is important to give netdata a star at GitHub</a></strong>.
                     </div>
-                    <hr/>
                     <div class="p">
                         Enjoy real-time performance monitoring!
                     </div>
                     <br/>
                     <div style="padding: 10px;"></div>
                     <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
+                    <div>
+                        <hr/>
+                    </div>
+                    <div>
+                        For progress reports and key netdata updates: <strong><a href="https://twitter.com/linuxnetdata" target="_blank">follow netdata on <i class="fa fa-twitter" aria-hidden="true"></i> twitter</a></strong>.
+                        <br/>
+                        <small>
+                            You can also <a href="https://www.facebook.com/linuxnetdata/" target="_blank">follow netdata on <i class="fa fa-facebook" aria-hidden="true"></i> facebook</a>,
+                            or <a href="https://github.com/firehol/netdata" target="_blank">watch netdata on <i class="fa fa-github" aria-hidden="true"></i> github</a>.
+                        </small>
+                    </div>
                 </div>
                 <div class="modal-footer">
                     <a href="#" onclick="notifyForUpdate(true); return false;" type="button" class="btn btn-default">Check Now</a>
                     <br/>
                     All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
-                    <form action="#">
-                    <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
-                    </form>
+                        <form action="#">
+                            <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
+                        </form>
                     </p>
                     Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
                     <p style="padding-top: 10px;"><small>
     </div>
 </body>
 </html>
-<script type="text/javascript" src="dashboard.js?v20161208-1"></script>
+<script type="text/javascript" src="dashboard.js?v20170118-11"></script>