]> arthur.barton.de Git - netdata.git/blob - web/index.html
Merge remote-tracking branch 'firehol/master'
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4     <title>netdata dashboard</title>
5     <meta name="application-name" content="netdata">
6
7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8     <meta charset="utf-8">
9     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
10     <meta name="viewport" content="width=device-width, initial-scale=1">
11     <meta name="apple-mobile-web-app-capable" content="yes">
12     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
13     <meta name="author" content="costa@tsaousis.gr">
14
15     <link rel="shortcut icon" href="images/seo-performance-multi-size.ico">
16
17     <link rel="apple-touch-icon" href="images/seo-performance-72.png">
18     <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png">
19     <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png">
20
21     <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png">
22     <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png">
23     <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png">
24     <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png">
25     <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png">
26     <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png">
27     <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png">
28     <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png">
29
30     <meta property="og:locale" content="en_US" />
31     <meta property="og:image" content="http://my-netdata.io/images/post.png"/>
32     <meta property="og:url" content="http://my-netdata.io/"/>
33     <meta property="og:type" content="website"/>
34     <meta property="og:site_name" content="netdata"/>
35     <meta property="og:title" content="netdata - real-time performance monitoring, done right!"/>
36     <meta property="og:description" content="Stunning real-time dashboards, blazingly fast and extremely interactive. Zero configuration, zero dependencies, zero maintenance." />
37
38     <style>
39
40     /* prevent body from hiding under the navbar */
41     body {
42         padding-top: 50px;
43     }
44
45     .loadOverlay {
46         position: absolute;
47         top: 0px;
48         left: 0px;
49         width: 100%;
50         height:100%;
51         z-index: 2000;
52         font-size: 10vh;
53         font-family: sans-serif;
54         padding: 40vh 0 40vh 0;
55         font-weight: bold;
56         text-align: center;
57     }
58
59     .modal-wide .modal-dialog {
60         width: 80%;
61     }
62
63     /* fix # anchors scrolling under the navbar
64        https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
65      */
66     h1 {
67         position: relative;
68         z-index: -1;
69     }
70     h2 {
71         position: relative;
72         z-index: -2;
73     }
74     h1:before, h2:before {
75         display: block;
76         content: " ";
77         margin-top: -70px;
78         height: 70px;
79         visibility: hidden;
80     }
81
82     .p {
83         display: block;
84         margin-top: 15px;
85     }
86
87     .option-row,
88     .option-control {
89         vertical-align: top;
90         padding: 10px;
91         padding-top: 30px;
92         padding-left: 30px;
93     }
94
95     .option-info {
96         padding: 10px;
97     }
98
99     .chart-message {
100         display: block;
101         margin-top: 10px;
102     }
103
104     .container {
105         width: 90% !important;
106     }
107
108     #masthead h1 {
109         /*font-size: 30px;*/
110         line-height: 1;
111         padding-top: 30px;
112     }
113
114     #masthead .well {
115         margin-top:4%;
116     }
117
118     /* fix the navbar shifting when a modal is open */
119     /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
120     body.modal-open{
121         width: 100% !important;
122         padding-right: 0 !important;
123 /*      overflow-y: scroll !important; */
124 /*      position: fixed !important;*/
125         overflow: visible;
126     }
127
128     /*
129      * Side navigation
130      *
131      * Scrollspy and affixed enhanced navigation to highlight sections and secondary
132      * sections of docs content.
133      */
134
135     .affix {
136         position: static;
137         top: 70px !important;
138         /*width: 220px;*/
139     }
140
141     .affix-top {
142         /*width: 220px;*/
143     }
144
145     .dashboard-sidebar {
146         max-height: calc(100% - 70px) !important;
147         overflow-y: auto;
148         /*width: 220px !important;*/
149     }
150
151     /* By default it's not affixed in mobile views, so undo that */
152     .dashboard-sidebar.affix {
153         position: static;
154     }
155
156     @media (min-width: 768px) {
157         .dashboard-sidebar {
158             padding-left: 20px;
159         }
160     }
161
162     /* First level of nav */
163     .dashboard-sidenav {
164         margin-top: 20px;
165         margin-bottom: 20px;
166     }
167
168     /* All levels of nav */
169     .dashboard-sidebar .nav > li > a {
170         display: block;
171         padding: 4px 20px;
172         font-size: 13px;
173         font-weight: 500;
174         color: #767676;
175     }
176     .dashboard-sidebar .nav > li > a:hover,
177     .dashboard-sidebar .nav > li > a:focus {
178         padding-left: 19px;
179         color: #563d7c;
180         text-decoration: none;
181         background-color: transparent;
182         border-left: 1px solid #563d7c;
183     }
184     .dashboard-sidebar .nav > .active > a,
185     .dashboard-sidebar .nav > .active:hover > a,
186     .dashboard-sidebar .nav > .active:focus > a {
187         padding-left: 18px;
188         font-weight: bold;
189         color: #563d7c;
190         background-color: transparent;
191         border-left: 2px solid #563d7c;
192     }
193
194     /* Nav: second level (shown on .active) */
195     .dashboard-sidebar .nav .nav {
196         display: none; /* Hide by default, but at >768px, show it */
197         padding-bottom: 10px;
198     }
199     .dashboard-sidebar .nav .nav > li > a {
200         padding-top: 1px;
201         padding-bottom: 1px;
202         padding-left: 30px;
203         font-size: 12px;
204         font-weight: normal;
205     }
206     .dashboard-sidebar .nav .nav > li > a:hover,
207     .dashboard-sidebar .nav .nav > li > a:focus {
208         padding-left: 29px;
209     }
210     .dashboard-sidebar .nav .nav > .active > a,
211     .dashboard-sidebar .nav .nav > .active:hover > a,
212     .dashboard-sidebar .nav .nav > .active:focus > a {
213         padding-left: 28px;
214         font-weight: 500;
215     }
216
217     .dropdown-menu {
218         min-width: 200px;
219     }
220     .dropdown-menu.columns-2 {
221         margin: 0;
222         padding: 0;
223         width: 400px;
224     }
225     .dropdown-menu li a {
226         padding: 5px 15px;
227         font-weight: 300;
228     }
229     .dropdown-menu.multi-column {
230         overflow-x: hidden;
231     }
232     .multi-column-dropdown {
233         list-style: none;
234         padding: 0;
235     }
236     .multi-column-dropdown li a {
237         display: block;
238         clear: both;
239         line-height: 1.428571429;
240         white-space: normal;
241     }
242     .multi-column-dropdown li a:hover {
243         text-decoration: none;
244         color: #f5f5f5;
245         background-color: #262626;
246     }
247     .scrollable-menu {
248         height: auto;
249         max-height: 80vh;
250         overflow-x: hidden;
251     }
252
253     /* Back to top (hidden on mobile) */
254     .back-to-top,
255     .dashboard-theme-toggle {
256         display: none;
257         padding: 4px 10px;
258         margin-top: 10px;
259         margin-left: 10px;
260         font-size: 12px;
261         font-weight: 500;
262         color: #999;
263     }
264     .back-to-top:hover,
265     .dashboard-theme-toggle:hover {
266         color: #563d7c;
267         text-decoration: none;
268     }
269     .dashboard-theme-toggle {
270         margin-top: 0;
271     }
272
273     @media (min-width: 768px) {
274         .back-to-top,
275         .dashboard-theme-toggle {
276             display: block;
277         }
278
279         /* Widen the fixed sidebar */
280         .dashboard-sidebar.affix,
281         .dashboard-sidebar.affix-top,
282         .dashboard-sidebar.affix-bottom {
283             width: 200px !important;
284         }
285
286         .dashboard-sidebar.affix {
287             position: fixed; /* Undo the static from mobile first approach */
288             top: 20px;
289         }
290
291         .dashboard-sidebar.affix-bottom {
292             position: absolute; /* Undo the static from mobile first approach */
293         }
294
295         .dashboard-sidebar.affix-bottom .dashboard-sidenav,
296         .dashboard-sidebar.affix .dashboard-sidenav {
297             margin-top: 0;
298             margin-bottom: 0;
299         }
300     }
301
302     /* Show and affix the side nav when space allows it */
303     @media (min-width: 992px) {
304         .dashboard-sidebar .nav > .active > ul {
305             display: block;
306         }
307
308         /* Widen the fixed sidebar */
309         .dashboard-sidebar.affix,
310         .dashboard-sidebar.affix-top,
311         .dashboard-sidebar.affix-bottom {
312             width: 200px !important;
313         }
314         .dashboard-sidebar.affix {
315             position: fixed; /* Undo the static from mobile first approach */
316             top: 20px;
317         }
318         .dashboard-sidebar.affix-bottom {
319             position: absolute; /* Undo the static from mobile first approach */
320         }
321         .dashboard-sidebar.affix-bottom .dashboard-sidenav,
322         .dashboard-sidebar.affix .dashboard-sidenav {
323             margin-top: 0;
324             margin-bottom: 0;
325         }
326     }
327
328     @media (min-width: 1200px) {
329         /* Widen the fixed sidebar again */
330         .dashboard-sidebar.affix-bottom,
331         .dashboard-sidebar.affix-top,
332         .dashboard-sidebar.affix {
333             width: 263px;
334         }
335     }
336     </style>
337
338     <!-- check which theme to use -->
339     <script type="text/javascript">
340         // --------------------------------------------------------------------
341         // urlOptions
342
343         var urlOptions = {
344             hash: '#',
345             theme: null,
346             help: null,
347             pan_and_zoom: false,
348             after: 0,
349             before: 0,
350             nowelcome: 0,
351             hasProperty: function(property) {
352                 // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
353                 return typeof this[property] !== 'undefined';
354             }
355         };
356
357         function netdataPanAndZoomCallback(status, after, before) {
358             urlOptions.pan_and_zoom = status;
359             urlOptions.after = after;
360             urlOptions.before = before;
361             netdataHashUpdate();
362         }
363
364         function netdataHashUpdate() {
365             history.replaceState(null, '', netdataHash());
366         }
367
368         function netdataHash() {
369             var hash = urlOptions.hash;
370
371             if(urlOptions.pan_and_zoom === true) {
372                 hash += ';after='  + urlOptions.after.toString() +
373                         ';before=' + urlOptions.before.toString();
374             }
375
376             if(urlOptions.theme !== null)
377                 hash += ';theme=' + urlOptions.theme.toString();
378
379             if(urlOptions.help !== null)
380                 hash += ';help=' + urlOptions.help.toString();
381
382             return hash;
383         }
384
385         function netdataHashParse() {
386             var variables = document.location.hash.split(';');
387             var len = variables.length;
388             while(len--) {
389                 if(len !== 0) {
390                     var p = variables[len].split('=');
391                     if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
392                         urlOptions[p[0]] = p[1];
393                 }
394                 else {
395                     if(variables[len].length > 0)
396                         urlOptions.hash = variables[len];
397                 }
398             }
399
400             if(urlOptions.before > 0 && urlOptions.after > 0)
401                 urlOptions.pan_and_zoom = true;
402
403             // console.log(urlOptions);
404         }
405
406         netdataHashParse();
407
408         // --------------------------------------------------------------------
409         // check options that should be processed before loading netdata.js
410         
411         function loadLocalStorage(name) {
412             var ret = null;
413
414             try {
415                 if(typeof Storage !== "undefined" && typeof localStorage === 'object')
416                     ret = localStorage.getItem(name);
417             }
418             catch(error) {
419                 ;
420             }
421
422             if(typeof ret === 'undefined' || ret === null)
423                 return null;
424
425             // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
426
427             return ret;
428         }
429
430         function saveLocalStorage(name, value) {
431             // console.log('saving: ' + name.toString() + ' = ' + value.toString());
432             try {
433                 if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
434                     localStorage.setItem(name, value.toString());
435                     return true;
436                 }
437             }
438             catch(error) {
439                 ;
440             }
441
442             return false;
443         }
444
445         function getTheme(def) {
446             var ret = loadLocalStorage('netdataTheme');
447             if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
448                 return def;
449             else
450                 return ret;
451         }
452
453         function setTheme(theme) {
454             if(theme === netdataTheme) return false;
455             return saveLocalStorage('netdataTheme', theme);
456         }
457
458         var netdataTheme = getTheme('slate');
459         var netdataShowHelp = true;
460
461         if(urlOptions.theme !== null) {
462             setTheme(urlOptions.theme);
463             netdataTheme = urlOptions.theme;
464         }
465         else
466             urlOptions.theme = netdataTheme;
467
468         if(urlOptions.help !== null) {
469             saveLocalStorage('options.show_help', urlOptions.help);
470             netdataShowHelp = urlOptions.help;
471         }
472         else {
473             urlOptions.help = loadLocalStorage('options.show_help');
474         }
475
476         // --------------------------------------------------------------------
477         // registry call back to render my-netdata menu
478
479         var netdataRegistryCallback = function(machines_array) {
480             var el = '';
481             var a1 = '';
482             var found = 0;
483
484             if(machines_array) {
485                 function name_comparator_desc(a, b) {
486                     if (a.name > b.name) return -1;
487                     if (a.name < b.name) return 1;
488                     return 0;
489                 }
490
491                 var machines = machines_array.sort(name_comparator_desc);
492                 var len = machines.length;
493                 while(len--) {
494                     var u = machines[len];
495                     found++;
496                     el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
497                     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>';
498                 }
499             }
500
501             if(!found) {
502                 if(machines)
503                     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>';
504                 else
505                     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>';
506
507                 a1 += '<li><a href="#" onClick="return false;">&nbsp;</a></li>';
508
509                 el += '<li role="separator" class="divider"></li>' +
510                         '<li><a href="//london.netdata.rocks/default.html">EU - London (DigitalOcean.com)</a></li>' +
511                         '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
512                         '<li><a href="//athens.netdata.rocks/default.html">EU - Athens</a></li>';
513                 a1 += '<li role="separator" class="divider"></li>' +
514                         '<li><a href="#">&nbsp;</a></li>' +
515                         '<li><a href="#">&nbsp;</a></li>'+
516                         '<li><a href="#">&nbsp;</a></li>';
517             }
518
519             el += '<li role="separator" class="divider"></li>';
520             a1 += '<li role="separator" class="divider"></li>';
521
522             el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
523             a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-cog" aria-hidden="true" style="color: #999;"></i></a></li>'
524
525             document.getElementById('mynetdata_servers').innerHTML = el;
526             document.getElementById('mynetdata_servers2').innerHTML = el;
527             document.getElementById('mynetdata_actions1').innerHTML = a1;
528
529             gotoServerInit();
530         };
531
532     </script>
533
534     <!-- load the dashboard manager - it will do the rest -->
535     <script type="text/javascript" src="dashboard.js?v41"></script>
536 </head>
537 <body data-spy="scroll" data-target="#sidebar">
538     <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
539         netdata<br/><div style="font-size: 3vh;">Real-time performance monitoring, done right!</div>
540     </div>
541     <script type="text/javascript">
542         // change the loadOverlay colors ASAP to match the theme
543         document.getElementById('loadOverlay').style = (urlOptions.theme === 'slate')?"background-color:#272b30; color: #373b40;":"background-color:#fff; color: #ddd;";
544     </script>
545     <nav class="navbar navbar-default navbar-fixed-top" role="banner">
546         <div class="container">
547             <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
548                 <ul class="nav navbar-nav">
549                     <li class="dropdown">
550                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
551                         <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
552                             <div class="row">
553                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
554                                     <ul id="mynetdata_servers" class="multi-column-dropdown">
555                                         <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
556                                     </ul>
557                                 </div>
558                                 <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
559                                     <ul id="mynetdata_actions1" class="multi-column-dropdown">
560                                     <li style="color: #999;">&nbsp;</li>
561                                     </ul>
562                                 </div>
563                             </div>
564                         </ul>
565                     </li>
566                 </ul>
567             </nav>
568             <div class="navbar-header">
569                 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
570                     <span class="sr-only">Toggle navigation</span>
571                     <span class="icon-bar"></span>
572                     <span class="icon-bar"></span>
573                     <span class="icon-bar"></span>
574                 </button>
575                 <a href="/" class="navbar-brand" id="hostname">netdata</a>
576             </div>
577             <nav class="collapse navbar-collapse navbar-right" role="navigation">
578                 <ul class="nav navbar-nav">
579                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
580                     <li class="hidden-sm"><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
581                     <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal"><i class="fa fa-cloud-download"></i> update</a></li>
582                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
583                     <li class="dropdown hidden-md hidden-lg hidden-xs">
584                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
585                         <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
586                             <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-cog"></i> settings</a></li>
587                             <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
588                             <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
589                         </ul>
590                     </li>
591                     <li class="dropdown hidden-sm hidden-md hidden-lg">
592                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
593                         <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
594                             <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
595                         </ul>
596                     </li>
597                 </ul>
598             </nav>
599     </nav>
600         </div>
601     </nav>
602
603     <div id="masthead" style="display: none;">
604         <div class="container">
605             <div class="row">
606                 <div class="col-md-7">
607                     <h1>Netdata
608                         <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
609                     </h1>
610                 </div>
611                 <div class="col-md-5">
612                     <div class="well well-lg">
613                         <div class="row">
614                         <div class="col-md-6">
615                             <b>Drag</b> charts to pan.
616                             <b>Shift + wheel</b> on them, to zoom in and out.
617                             <b>Double-click</b> on them, to reset.
618                             <b>Hover</b> on them too!
619                             </div>
620                         <div class="col-md-6">
621                             <div data-netdata="system.intr" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dygraph-type="line" data-dygraph-strokewidth="3" data-dygraph-smooth="true" data-dygraph-highlightcirclesize="6" data-after="-90" data-height="60px" data-colors="#C66"></div>
622                             </div>
623                         </div>
624                     </div>
625                 </div>
626             </div>
627         </div>
628     </div>
629
630     <div class="container">
631         <div class="row">
632             <div class="col-md-10" role="main">
633                 <div id="charts_div"></div>
634             </div>
635             <div class="col-md-2" role="complementary">
636                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
637             </div>
638         </div>
639     </div>
640
641     <div id="footer" class="container" style="display: none;">
642         <div class="row">
643             <div class="col-md-10" role="main">
644                 <div class="p">
645                     <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
646                     <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
647                     Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
648                 </div>
649                 <div class="p">
650                     <small>
651                         <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
652
653                         <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
654                         <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
655
656                         <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
657                         <i class="fa fa-copyright"></i> Copyright 2009-2012, Splunk Inc., <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">New BSD License</a>
658
659                         <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
660                         <i class="fa fa-copyright"></i> Copyright 2009-2015, Ben Pickles, <a href="https://github.com/benpickles/peity/blob/master/MIT-LICENCE" target="_blank">MIT License</a>
661
662                         <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
663                         <i class="fa fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a>
664
665                         <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
666                         <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
667
668                         <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
669                         <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
670
671                         <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
672                         <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
673
674                         <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
675                         <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>
676
677                         <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
678                         <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>
679
680                         <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
681                         <i class="fa fa-copyright"></i> Copyright Marc J. Schmidt, <a href="https://github.com/marcj/css-element-queries/blob/master/LICENSE" target="_blank">MIT License</a>
682
683                         <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
684                         <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>
685
686                         <i class="fa fa-circle"></i> <a href="http://www.iconsdb.com/soylent-red-icons/seo-performance-icon.html" target="_blank">IconsDB.com Icons</a>, Icons provided as CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.
687
688                         <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
689                         <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
690
691                         <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
692                         <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
693
694                         <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
695                         <i class="fa fa-copyright"></i> Copyright 2013, Masayuki Tanaka, <a href="https://github.com/masayuki0812/c3/blob/master/LICENSE" target="_blank">MIT License</a>
696
697                         <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
698                         <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
699
700                     </small>
701                 </div>
702             </div>
703         </div>
704     </div>
705
706     <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
707         <div class="modal-dialog modal-lg" role="document">
708             <div class="modal-content">
709                 <div class="modal-header">
710                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
711                     <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
712                 </div>
713                 <div class="modal-body">
714                         <div class="p">
715                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> is the fastest way to visualize metrics. It is a resource efficient, highly optimized system for collecting and visualizing any type of real-time time series data, from CPU usage, disk activity, SQL queries, API calls, web site visitors, etc.
716                         </div>
717                         <div class="p">
718                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> tries to visualize the truth of <b>now</b>, in its <b>greatest detail</b>, so that you can get insights of what is happening now and what just happened, on your systems and applications.
719                         </div>
720                         <div class="p">
721                         To make a chart in <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>, you just need a <b>number</b>. Just a number you can read somehow. <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> will turn this number to a real time, interactive, web chart. For collecting these numbers, it supports <a href="https://github.com/firehol/netdata/wiki/External-Plugins" target="_blank">external plugins</a>, even <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">shell</a> or <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">node.js</a> plugins. Any computer program, in any language, that can print a few lines of text on its standard output, can be a netdata data collector.
722                         </div>
723                         <div class="p">
724                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> can embed charts everywhere, like this one <div data-netdata="system.cpu" data-dimensions="system" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-system-at="system.cpu.system.modal.1"></div> (my CPU system usage which is <span id="system.cpu.system.modal.1" style="display: inline-block; width: 40px; text-align: right;"></span>%),
725                         or this one <div data-netdata="ipv4.tcppackets" data-dimensions="received" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-received-at="ipv4.tcppackets.received.modal.1"></div> (my IPv4 received TCP packets, which are <span id="ipv4.tcppackets.received.modal.1" style="display: inline-block; width: 60px; text-align: right;"></span>/second).
726                         </div>
727                         <div class="p">
728                         You can have <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> charts on your site too. Just give it a <code>div</code> and a real time chart, zoomable and draggable will appear (try it even on these tiny ones - <b>drag</b> them to pan horizontally, <b>shift + drag</b> to zoom in, on <b>chrome shift + mouse wheel</b> to zoom in/out, <b>double click</b> on them to reset them - don't be afraid of <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> performance - <a href="https://github.com/firehol/netdata/wiki/Performance" target="_blank">a raspberry pi 2 can sustain 300 charts updates per second</a>!).
729                         </div>
730                         <div class="p">
731                         For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
732                         </div>
733                 </div>
734                 <div class="modal-footer">
735                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
736                 </div>
737             </div>
738         </div>
739     </div>
740
741     <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
742         <div class="modal-dialog modal-lg" role="document">
743             <div class="modal-content">
744                 <div class="modal-header">
745                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
746                     <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
747                 </div>
748                 <div class="modal-body">
749
750                     <h4>Dygraphs (line, area and stacked area charts)</h4>
751
752                     <!-- Nav tabs -->
753                     <ul class="nav nav-tabs" role="tablist">
754                         <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
755                         <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
756                     </ul>
757
758                     <!-- Tab panes -->
759                     <div class="tab-content">
760                         <div role="tabpanel" class="tab-pane active" id="help_mouse">
761                             <div class="p">
762                                 <h4>Mouse Over / Hover</h4>
763                                 Mouse over on a chart to show, at its legend, the values for the timestamp under the mouse (the chart will also highlight the point at the chart).
764                                 <br/>
765                                 All the other visible charts will also show and highlight their values for the same timestamp.
766                             </div>
767                             <hr/>
768                             <div class="p">
769                                 <h4>Drag Chart Contents</h4>
770                                 Drag the contents of a chart to pan it horizontally.
771                                 <br/>
772                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
773                                 <br/>
774                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
775                             </div>
776                             <hr/>
777                             <div class="p">
778                                 <h4>Double Click</h4>
779                                 Double Click a chart to reset all the charts to their default auto-refreshing state.
780                             </div>
781                             <hr/>
782                             <div class="p">
783                                 <h4>SHIFT + Drag</h4>
784                                 While pressing the shift key, click on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
785                                 <ul>
786                                     <li>The already loaded chart contents are zoomed (low resolution)</li>
787                                     <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
788                                 </ul>
789                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
790                             </div>
791                             <hr/>
792                             <div class="p">
793                                 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
794                                 While pressing the shift key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
795                                 <br/>
796                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
797                             </div>
798                             <hr/>
799                             <div class="p">
800                                 <h4>Legend Operations</h4>
801                                 Click on the label or value of a dimension, will select / un-select this dimension.
802                                 <br/>
803                                 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
804                             </div>
805                         </div>
806                         <div role="tabpanel" class="tab-pane" id="help_touch">
807                             <div class="p">
808                                 <h4>Single Tap</h4>
809                                 Single Tap on the contents of a chart to show, at its legend, the values for the timestamp tapped (the chart will also highlight the point at the chart).
810                                 <br/>
811                                 All the other visible charts will also show and highlight their values for the same timestamp.
812                             </div>
813                             <hr/>
814                             <div class="p">
815                                 <h4>Drag Chart Contents</h4>
816                                 Touch and Drag the contents of a chart to pan it horizontally.
817                                 <br/>
818                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
819                                 <br/>
820                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
821                             </div>
822                             <hr/>
823                             <div class="p">
824                                 <h4>Double Tap</h4>
825                                 Double tap a chart to reset all the charts to their default auto-refreshing state.
826                             </div>
827                             <hr/>
828                             <div class="p">
829                                 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
830                                 With two fingers, zoom in or out.
831                                 <br/>
832                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
833                             </div>
834                             <hr/>
835                             <div class="p">
836                                 <h4>Legend Operations</h4>
837                                 Tap on the label or value of a dimension, will select / un-select this dimension.
838                             </div>
839                         </div>
840                     </div>
841                 </div>
842                 <div class="modal-footer">
843                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
844                 </div>
845             </div>
846         </div>
847     </div>
848
849     <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
850         <div class="modal-dialog modal-lg" role="document">
851             <div class="modal-content">
852                 <div class="modal-header">
853                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
854                     <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
855                 </div>
856                 <div class="modal-body">
857                     <center>
858                         <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
859                         <br/>
860                         Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
861                         <br/>
862                         To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
863                     </center>
864                     <div style="padding: 10px;"></div>
865
866                     <!-- Nav tabs -->
867                     <ul class="nav nav-tabs" role="tablist">
868                         <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
869                         <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
870                         <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
871                     </ul>
872
873                     <!-- Tab panes -->
874                     <div class="tab-content">
875                         <div role="tabpanel" class="tab-pane active" id="settings_performance">
876                             <form id="optionsForm1" method="get" class="form-horizontal">
877                                 <div class="form-group">
878                                     <table>
879                                     <tr class="option-row">
880                                         <td class="option-control"><input id="stop_updates_when_focus_is_lost" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="On Focus" data-off="Always" data-width="110px"></td>
881                                         <td class="option-info"><strong>When to refresh the charts?</strong><br/>
882                                             <small>When set to <b>On Focus</b>, the charts will stop being updated if the page / tab does not have the focus of the user. When set to <b>Always</b>, the charts will always be refreshed. Set it to <b>On Focus</b> it to lower the CPU requirements of the browser (and extend the battery of laptops and tablets) when this page does not have your focus. Set to <b>Always</b> to work on another window (i.e. change the settings of something) and have the charts auto-refresh in this window.</small>
883                                         </td>
884                                         </tr>
885                                     <tr class="option-row">
886                                         <td class="option-control">
887                                         <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
888                                         </td>
889                                         <td class="option-info"><strong>Which dimensions to show?</strong><br/>
890                                             <small>When set to <b>Non Zero</b>, dimensions that have all their values (within the current view) set to zero will not be transferred from the netdata server (except if all dimensions of the chart are zero, in which case this setting does nothing - all dimensions are transferred and shown). When set to <b>All</b>, all dimensions will always be shown. Set it to <b>Non Zero</b> to lower the data transferred between netdata and your browser, lower the CPU requirements of your browser (fewer lines to draw) and increase the focus on the legends (fewer entries at the legends).</small>
891                                         </td>
892                                         </tr>
893                                     <tr class="option-row">
894                                         <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
895                                         <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
896                                             <small>When set to <b>Destroy</b>, charts that are not in the current viewport of the browser (are above, or below the visible area of the page), will be destroyed and re-created if and when they become visible again. When set to <b>Hide</b>, the not-visible charts will be just hidden, to simplify the DOM and speed up your browser. Set it to <b>Destroy</b>, to lower the memory requirements of your browser. Set it to <b>Hide</b> for smoother page scrolling.</small>
897                                         </td>
898                                         </tr>
899                                     </table>
900                                 </div>
901                             </form>
902                         </div>
903                         <div role="tabpanel" class="tab-pane" id="settings_sync">
904                             <form id="optionsForm2" method="get" class="form-horizontal">
905                                 <div class="form-group">
906                                     <table>
907                                     <tr class="option-row">
908                                         <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
909                                         <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
910                                             <small>When set to <b>parallel</b>, visible charts are refreshed in parallel (all queries are sent to netdata server in parallel) and are rendered asynchronously. When set to <b>sequential</b> charts are refreshed one after another. Set it to parallel if your browser can cope with it (most modern browsers do), set it to sequential if you work on an older/slower computer.</small>
911                                         </td>
912                                         </tr>
913                                     <tr class="option-row" id="concurrent_refreshes_row">
914                                         <td class="option-control"></td>
915                                         <td class="option-info">
916                                             <table>
917                                             <tr class="option-row">
918                                             <td class="option-control">
919                                             <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
920                                             </td>
921                                             <td class="option-info">
922                                             <strong>Shall we re-sync chart refreshes?</strong><br/>
923                                             <small>When set to <b>Resync</b>, the dashboard will attempt to re-synchronize all the charts so that they are refreshed concurrently. When set to <b>Best Effort</b>, each chart may be refreshed with a little time difference to the others. Normally, the dashboard starts refreshing them in parallel, but depending on the speed of your computer and the network latencies, charts start having a slight time difference. Setting this to <b>Resync</b> will attempt to re-synchronize the charts on every update. Setting it to <b>Best Effort</b> may lower the pressure on your browser and the network.</small>
924                                             </td>
925                                             </tr>
926                                             </table>
927                                         </td>
928                                         </tr>
929                                     <tr class="option-row">
930                                         <td class="option-control"><input id="sync_selection" type="checkbox" checked data-toggle="toggle" data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
931                                         <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
932                                             <small>When enabled, a selection on one chart will automatically select the same time on all other visible charts and the legends of all visible charts will be updated to show the selected values. When disabled, only the chart getting the user's attention will be selected. Enable it to get better insights of the data. Disable it if you are on a very slow computer that cannot actually do it.</small>
933                                         </td>
934                                         </tr>
935                                     <tr class="option-row">
936                                         <td class="option-control"><input id="sync_pan_and_zoom" type="checkbox" checked data-toggle="toggle"  data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
937                                         <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
938                                             <small>When enabled, pan and zoom operations on a chart will be replicated to all charts (even the ones that are not currently visible - of course only when they will become visible). When disabled, pan and zoom operations will not be propagated to other charts.</small>
939                                         </td>
940                                         </tr>
941                                     </table>
942                                 </div>
943                             </form>
944                         </div>
945                         <div role="tabpanel" class="tab-pane" id="settings_visual">
946                             <form id="optionsForm3" method="get" class="form-horizontal">
947                                 <div class="form-group">
948                                     <table>
949                                     <tr class="option-row">
950                                         <td class="option-control"><input id="netdata_theme_control" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="Dark" data-off="White" data-width="110px"></td>
951                                         <td class="option-info"><strong>Which theme to use?</strong><br/>
952                                             <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
953                                             <br/>
954                                             <b>Switching this will reload the dashboard</b>.
955                                             </small>
956                                         </td>
957                                         </tr>
958                                     <tr class="option-row">
959                                         <td class="option-control"><input id="show_help" type="checkbox" checked data-toggle="toggle" data-on="Help Me" data-off="No Help" data-width="110px"></td>
960                                         <td class="option-info"><strong>Do you need help?</strong><br/>
961                                             <small>Netdata can show some help in some areas to help you use the dashboard. If all these balloons bother you, disable them using this switch.
962                                             <br/>
963                                             <b>Switching this will reload the dashboard</b>.
964                                             </small>
965                                         </td>
966                                         </tr>
967                                     <tr class="option-row">
968                                         <td class="option-control"><input id="pan_and_zoom_data_padding" type="checkbox" checked data-toggle="toggle"  data-on="Pad" data-off="Don't Pad" data-width="110px"></td>
969                                         <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
970                                             <small>When set to <b>Pad</b> the charts will be padded with more data, both before and after the visible area, thus giving the impression the whole database is loaded. This padding will happen only after the first pan or zoom operation on the chart (initially all charts have only the visible data). When set to <b>Don't Pad</b> only the visible data will be transfered from the netdata server, even after the first pan and zoom operation.</small>
971                                         </td>
972                                         </tr>
973                                     <tr class="option-row">
974                                         <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle"  data-on="Smooth" data-off="Rough" data-width="110px"></td>
975                                         <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
976                                             <small>When set to <b>Smooth</b> the charts libraries that support it, will plot smooth curves instead of simple straight lines to connect the points.
977                                             <br/>
978                                             Keep in mind <a href="http://dygraphs.com" target="_blank">dygraphs</a>, the main charting library in netdata dashboards, can only smooth line charts. It cannot smooth area or stacked charts. When set to <b>Rough</b>, this setting can lower the CPU resources consumed by your browser.</small>
979                                         </td>
980                                         </tr>
981                                     </table>
982                                 </div>
983                             </form>
984                         </div>
985                     </div>
986                 </div>
987                 <div class="modal-footer">
988                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
989                 </div>
990             </div>
991         </div>
992     </div>
993
994
995     <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
996         <div class="modal-dialog" role="document">
997             <div class="modal-content">
998                 <div class="modal-header">
999                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1000                     <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
1001                 </div>
1002                 <div class="modal-body">
1003                     Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
1004                     <br/>
1005                     <div style="padding: 10px;"></div>
1006                     <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
1007                 </div>
1008                 <div class="modal-footer">
1009                     <a href="#" onclick="notifyForUpdate(true); return false;" type="button" class="btn btn-default">Check Now</a>
1010                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1011                 </div>
1012             </div>
1013         </div>
1014     </div>
1015
1016     <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
1017         <div class="modal-dialog" role="document">
1018             <div class="modal-content">
1019                 <div class="modal-header">
1020                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1021                     <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
1022                 </div>
1023                 <div class="modal-body">
1024                     You are about to delete, from your personal list of netdata servers, the following server:
1025                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1026                     <b><span id="deleteRegistryServerName2"></span></b>
1027                     <br/>
1028                     <b><span id="deleteRegistryServerURL"></span></b>
1029                     </p>
1030                     Are you sure you want to do this?
1031                     <br/>
1032                     <div style="padding: 10px;"></div>
1033                     <small>Keep in mind, this server will be added back if and when you visit it again.</small>
1034                     <br/>
1035                     <div id="deleteRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1036                 </div>
1037                 <div class="modal-footer">
1038                     <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
1039                     <a href="#" onclick="notifyForDeleteRegistry(true); return false;" type="button" class="btn btn-danger">delete it</a>
1040                 </div>
1041             </div>
1042         </div>
1043     </div>
1044
1045     <div class="modal fade" id="switchRegistryModal" tabindex="-1" role="dialog" aria-labelledby="switchRegistryModalLabel">
1046         <div class="modal-dialog" role="document">
1047             <div class="modal-content">
1048                 <div class="modal-header">
1049                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1050                     <h4 class="modal-title" id="switchRegistryModalLabel">Switch Netdata Registry Identity</h4>
1051                 </div>
1052                 <div class="modal-body">
1053                     You can copy and paste the following ID to all your browsers (e.g. work and home).
1054                     <br/>
1055                     All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
1056                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1057                     <form action="#">
1058                     <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
1059                     </form>
1060                     </p>
1061                     Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
1062                     <p style="padding-top: 10px;"><small>
1063                         Keep in mind that:
1064                         <ul>
1065                             <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li>
1066                             <li>both IDs (your old and the new) must list this netdata at their personal lists.</li>
1067                             <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li>
1068                             <li>to get a new ID, just clear your browser cookies.</li>
1069                         </ul>
1070                     </small></p>
1071                     <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1072                 </div>
1073                 <div class="modal-footer">
1074                     <button type="button" class="btn btn-success" data-dismiss="modal">cancel</button>
1075                     <a href="#" onclick="notifyForSwitchRegistry(true); return false;" type="button" class="btn btn-danger">impersonate</a>
1076                 </div>
1077             </div>
1078         </div>
1079     </div>
1080
1081     <div class="modal fade" id="gotoServerModal" tabindex="-1" role="dialog" aria-labelledby="gotoServerModalLabel">
1082         <div class="modal-dialog" role="document">
1083             <div class="modal-content">
1084                 <div class="modal-header">
1085                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1086                     <h4 class="modal-title" id="gotoServerModalLabel"><span id="gotoServerName"></span></h4>
1087                 </div>
1088                 <div class="modal-body">
1089                     Checking known URLs for this server...
1090                     <div  style="padding-top: 20px;">
1091                         <table id="gotoServerList">
1092                         </table>
1093                     </div>
1094                     <p style="padding-top: 10px;"><small>
1095                         Checks may fail if you are viewing an HTTPS page and the server to be checked is HTTP only.
1096                     </small></p>
1097                     <div id="gotoServerResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1098                 </div>
1099                 <div class="modal-footer">
1100                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1101                 </div>
1102             </div>
1103         </div>
1104     </div>
1105
1106 <script type="text/javascript">
1107 var this_is_demo = null;
1108 function isdemo() {
1109     if(this_is_demo !== null) return this_is_demo;
1110     this_is_demo = false;
1111
1112     try {
1113         if(typeof document.location.hostname === 'string') {
1114             if(document.location.hostname.endsWith('.my-netdata.io') ||
1115                     document.location.hostname.endsWith('.mynetdata.io') ||
1116                     document.location.hostname.endsWith('.netdata.rocks') ||
1117                     document.location.hostname.endsWith('.firehol.org') ||
1118                     document.location.hostname.endsWith('.netdata.online'))
1119                     this_is_demo = true;
1120         }
1121     }
1122     catch(error) {
1123         ;
1124     }
1125
1126     return this_is_demo;
1127 }
1128
1129 if(isdemo()) {
1130     document.getElementById('masthead').style.display = 'block';
1131 }
1132
1133 function netdataURL(url) {
1134     if(typeof url === 'undefined')
1135         url = document.location.toString();
1136
1137     if(url.indexOf('#') !== -1)
1138         url = url.substring(0, url.indexOf('#'));
1139
1140     var hash = netdataHash();
1141
1142     // console.log('netdataURL: ' + url + hash);
1143
1144     return url + hash;
1145 }
1146
1147 function netdataReload(url) {
1148     var t = netdataURL(url);
1149     // console.log('netdataReload: ' + t);
1150     document.location = t;
1151
1152     // since we play with hash
1153     // this is needed to reload the page
1154     location.reload();
1155 }
1156
1157 var gotoServerValidateRemaining = 0;
1158 var gotoServerMiddleClick = false;
1159 var gotoServerStop = false;
1160 function gotoServerValidateUrl(id, guid, url) {
1161     var penaldy = 0;
1162     if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
1163             // we penalize https only if the current url is http
1164             // to allow the user walk through all its servers.
1165             penaldy = 500;
1166
1167     var finalURL = netdataURL(url);
1168
1169     setTimeout(function() {
1170         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>';
1171
1172         NETDATA.registry.hello(url, function(data) {
1173             if (data) {
1174                 // console.log('OK ' + id + ' URL: ' + url);
1175                 document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
1176
1177                 if(!gotoServerStop) {
1178                     gotoServerStop = true;
1179
1180                     if(gotoServerMiddleClick) {
1181                         window.open(finalURL, '_blank');
1182                         gotoServerMiddleClick = false;
1183                         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)';
1184                     }
1185                     else
1186                         document.location = finalURL;
1187                 }
1188             }
1189             else {
1190                 document.getElementById(guid + '-' + id + '-status').innerHTML = "failed!";
1191                 gotoServerValidateRemaining--;
1192                 if(gotoServerValidateRemaining <= 0) {
1193                     gotoServerMiddleClick = false;
1194                     document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
1195                 }
1196             }
1197         });
1198     }, (id * 50) + penaldy);
1199 }
1200
1201 function gotoServerModalHandler(guid) {
1202     // console.log('goto server: ' + guid);
1203
1204     gotoServerStop = false;
1205     var len = NETDATA.registry.machines[guid].alternate_urls.length;
1206
1207     document.getElementById('gotoServerResponse').innerHTML = '';
1208     document.getElementById('gotoServerList').innerHTML = '';
1209     document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
1210     $('#gotoServerModal').modal('show');
1211
1212     gotoServerValidateRemaining = len;
1213     while(len--)
1214         gotoServerValidateUrl(len, guid, NETDATA.registry.machines[guid].alternate_urls[len]);
1215
1216     return false;
1217 }
1218
1219 function gotoServerInit() {
1220     $(".registry_link").on('click', function(e) {
1221         if(e.which === 2) {
1222             e.preventDefault();
1223             gotoServerMiddleClick = true;
1224         }
1225         else {
1226             gotoServerMiddleClick = false;
1227         }
1228
1229         return true;
1230     });
1231 }
1232
1233 function switchRegistryModalHandler() {
1234     document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
1235     document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
1236     document.getElementById('switchRegistryResponse').innerHTML = '';
1237     $('#switchRegistryModal').modal('show');
1238 }
1239
1240 function notifyForSwitchRegistry() {
1241     var n = document.getElementById('switchRegistryPersonGUID').value;
1242
1243     if(n !== '' && n.length === 36) {
1244         NETDATA.registry.switch(n, function(result) {
1245             if(result !== null) {
1246                 $('#switchRegistryModal').modal('hide');
1247                 NETDATA.registry.init();
1248             }
1249             else {
1250                 document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
1251             }
1252         });
1253     }
1254     else
1255         document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
1256 }
1257
1258 var deleteRegistryUrl = null;
1259 function deleteRegistryModalHandler(guid, name, url) {
1260     deleteRegistryUrl = url;
1261     document.getElementById('deleteRegistryServerName').innerHTML = name;
1262     document.getElementById('deleteRegistryServerName2').innerHTML = name;
1263     document.getElementById('deleteRegistryServerURL').innerHTML = url;
1264     document.getElementById('deleteRegistryResponse').innerHTML = '';
1265     $('#deleteRegistryModal').modal('show');
1266 }
1267
1268 function notifyForDeleteRegistry() {
1269     if(deleteRegistryUrl) {
1270         NETDATA.registry.delete(deleteRegistryUrl, function(result) {
1271             if(result !== null) {
1272                 deleteRegistryUrl = null;
1273                 $('#deleteRegistryModal').modal('hide');
1274                 NETDATA.registry.init();
1275             }
1276             else {
1277                 document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
1278             }
1279         });
1280     }
1281 }
1282
1283 var options = {
1284     sparklines_registry: {},
1285     submenu_names: {},
1286     data: null,
1287     hostname: 'netdata_server', // will be overwritten by the netdata server
1288     categories: new Array(),
1289     categories_idx: {},
1290     families: new Array(),
1291     families_idx: {},
1292
1293     chartsPerRow: 0,
1294     chartsMinWidth: 1450,
1295     chartsHeight: 180,
1296     sparklinesHeight: 60,
1297 };
1298
1299 // generate a sparkline
1300 // used in the documentation
1301 function sparkline(chart, dimension, units) {
1302     var key = chart + '.' + dimension;
1303
1304     if(typeof units === 'undefined')
1305         units = '';
1306
1307     if(typeof options.sparklines_registry[key] === 'undefined')
1308         options.sparklines_registry[key] = { count: 1 };
1309     else
1310         options.sparklines_registry[key].count++;
1311
1312     key = key + '.' + options.sparklines_registry[key].count;
1313
1314     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 + ')';
1315
1316     return h;
1317 }
1318
1319 function chartsPerRow(total) {
1320     if(options.chartsPerRow === 0) {
1321         width = Math.floor(total / options.chartsMinWidth);
1322         if(width === 0) width = 1;
1323         return width;
1324     }
1325     else return options.chartsPerRow;
1326 }
1327
1328 function prioritySort(a, b) {
1329     if(a.priority < b.priority) return -1;
1330     if(a.priority > b.priority) return 1;
1331     if(a.name < b.name) return -1;
1332     return 1;
1333 }
1334
1335 function sortObjectByPriority(object) {
1336     var idx = {};
1337     var sorted = new Array();
1338
1339     for(var i in object) {
1340         if(typeof idx[i] === 'undefined') {
1341             idx[i] = object[i];
1342             sorted.push(i);
1343         }
1344     }
1345
1346     sorted.sort(function(a, b) {
1347         if(idx[a].priority < idx[b].priority) return -1;
1348         if(idx[a].priority > idx[b].priority) return 1;
1349         if(a < b) return -1;
1350         return 1;
1351     });
1352
1353     return sorted;
1354 }
1355
1356
1357 // ----------------------------------------------------------------------------
1358 // scroll to a section, without changing the browser history
1359
1360 function scrollToId(hash) {
1361     if(hash && hash != '') {
1362         var offset = $('#' + hash).offset();
1363         if(typeof offset !== 'undefined')
1364             $('html, body').animate({ scrollTop: offset.top }, 0);
1365     }
1366
1367     // we must return false to prevent the default action
1368     return false;
1369 }
1370
1371 // ----------------------------------------------------------------------------
1372
1373 function gaugeChart(title, width, dimensions, colors) {
1374     if(typeof colors === 'undefined')
1375         colors = '';
1376
1377     if(typeof dimensions === 'undefined')
1378         dimensions = '';
1379
1380     return '<div data-netdata="CHART_UNIQUE_ID"'
1381                             + ' data-dimensions="' + dimensions + '"'
1382                             + ' data-chart-library="gauge"'
1383                             + ' data-gauge-adjust="width"'
1384                             + ' data-title="' + title + '"'
1385                             + ' data-width="' + width + '"'
1386                             + ' data-before="0"'
1387                             + ' data-after="-CHART_DURATION"'
1388                             + ' data-points="CHART_DURATION"'
1389                             + ' data-colors="' + colors + '"'
1390                             + ' role="application"></div>';
1391 }
1392
1393 // ----------------------------------------------------------------------------
1394
1395 var menuData = {
1396     'system': {
1397         title: 'System Overview',
1398         info: 'Overview of the key system metrics.'
1399     },
1400
1401     'ap': {
1402         title: 'Access Points',
1403         info: undefined
1404     },
1405
1406     'tc': {
1407         title: 'Quality of Service',
1408         info: 'Netdata collects and visualizes tc class utilization using its <a href="https://github.com/firehol/netdata/blob/master/plugins.d/tc-qos-helper.sh" target="_blank">tc-helper plugin</a>. If you also use <a href="http://firehol.org/#fireqos" target="_blank">FireQOS</a> for setting up QoS, netdata automatically collects interface and class names. If your QoS configuration includes overheads calculation, the values shown here will include these overheads (the total bandwidth for the same interface as reported in the Network Interfaces section, will be lower than the total bandwidth reported here). Also, data collection may have a slight time difference compared to the interface (QoS data collection is implemented with a BASH script, so a shift in data collection of a few milliseconds should be justified).'
1409     },
1410
1411     'net': {
1412         title: 'Network Interfaces',
1413         info: 'Per network interface statistics collected from <code>/proc/net/dev</code>.'
1414     },
1415
1416     'ipv4': {
1417         title: 'IPv4 Networking',
1418         info: undefined
1419     },
1420
1421     'ipv6': {
1422         title: 'IPv6 Networking',
1423         info: undefined
1424     },
1425
1426     'ipvs': {
1427         title: 'IP Virtual Server',
1428         info: undefined
1429     },
1430
1431     'netfilter': {
1432         title: 'Firewall (netfilter)',
1433         info: undefined
1434     },
1435
1436     'cpu': {
1437         title: 'CPUs',
1438         info: undefined
1439     },
1440
1441     'mem': {
1442         title: 'Memory',
1443         info: undefined
1444     },
1445
1446     'disk': {
1447         title: 'Disks',
1448         info: 'Charts with performance information for all the system disks. Special care has been given to present disk performance metrics in a way compatible with <code>iostat -x</code>. netdata by default prevents rendering performance charts for individual partitions and unmounted virtual disks. Disabled charts can still be enabled by altering the relative settings in the netdata configuration file.'
1449     },
1450
1451     'sensors': {
1452         title: 'Sensors',
1453         info: undefined
1454     },
1455
1456     'nfsd': {
1457         title: 'File Server (nfsd)',
1458         info: undefined
1459     },
1460
1461     'apps': {
1462         title: 'Applications',
1463         info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported). The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1464         height: 1.5
1465     },
1466
1467     'users': {
1468         title: 'Users',
1469         info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1470         height: 1.5
1471     },
1472
1473     'groups': {
1474         title: 'User Groups',
1475         info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1476         height: 1.5
1477     },
1478
1479     'netdata': {
1480         title: 'Netdata Monitoring',
1481         info: undefined
1482     },
1483
1484     'example': {
1485         title: 'Example Charts',
1486         info: undefined
1487     },
1488
1489     'cgroup': {
1490         title: 'Container',
1491         info: undefined
1492     },
1493
1494     'cgqemu': {
1495         title: 'VM',
1496         info: undefined
1497     },
1498
1499     'memcached': {
1500         title: 'memcached',
1501         info: undefined
1502     },
1503
1504     'mysql': {
1505         title: 'MySQL',
1506         info: undefined
1507     },
1508
1509     'redis': {
1510         title: 'Redis',
1511         info: undefined
1512     },
1513
1514     'ipfs': {
1515         title: 'IPFS',
1516         info: undefined
1517     },
1518
1519     'phpfpm': {
1520         title: 'PHP-FPM',
1521         info: undefined,
1522     },
1523
1524     'nginx': {
1525         title: 'nginx',
1526         info: undefined,
1527     },
1528
1529     'apache': {
1530         title: 'Apache',
1531         info: undefined,
1532     },
1533
1534     'named': {
1535         title: 'named',
1536         info: undefined
1537     }
1538 };
1539
1540 var submenuData = {
1541     'mem.ksm': {
1542         title: 'Memory Deduper',
1543         info: 'Kernel Same-page Merging (KSM) performance monitoring, read from several files in <code>/sys/kernel/mm/ksm/</code>. KSM is a memory-saving de-duplication feature in the Linux kernel (since version 2.6.32). The KSM daemon ksmd periodically scans those areas of user memory which have been registered with it, looking for pages of identical content which can be replaced by a single write-protected page (which is automatically copied if a process later wants to update its content). KSM was originally developed for use with KVM (where it was known as Kernel Shared Memory), to fit more virtual machines into physical memory, by sharing the data common between them.  But it can be useful to any application which generates many instances of the same data.'
1544     },
1545
1546     'netfilter.conntrack': {
1547         title: 'Connection Tracker',
1548         info: 'Netfilter Connection Tracker performance monitoring, read from <code>/proc/net/stat/nf_conntrack</code>. The connection tracker keeps track of all connections of the machine, inbound and outbound. It works by keeping a database with all open connections, tracking network and address translation and connection expectations.'
1549     },
1550
1551     'netfilter.nfacct': {
1552         title: 'Bandwidth Accounting',
1553         info: 'The following information is read using the <code>nfacct.plugin</code>.'
1554     },
1555
1556     'netfilter.synproxy': {
1557         title: 'DDoS Protection',
1558         info: 'DDoS Protection performance monitoring read from <code>/proc/net/stat/synproxy</code>. <a href="https://github.com/firehol/firehol/wiki/Working-with-SYNPROXY" target="_blank">SYNPROXY</a> is a TCP SYN packets proxy. It is used to protect any TCP server (like a web server) from SYN floods and similar DDoS attacks. It is a netfilter module, in the Linux kernel (since version 3.12). It is optimized to handle millions of packets per second utilizing all CPUs available without any concurrency locking between the connections. It can be used for any kind of TCP traffic (even encrypted), since it does not interfere with the content itself.'
1559     }
1560 };
1561
1562 //
1563 // chartData works on the context of a chart
1564 // Its purpose is to set:
1565 //
1566 // info: the text above the charts
1567 // heads: the representation of the chart at the top the subsection (second level menu)
1568 // mainheads: the representation of the chart at the top of the section (first level menu)
1569 // colors: the dimension colors of the chart (the default colors are appended)
1570 // height: the ratio of the chart height relative to the default
1571 //
1572 var chartData = {
1573     'system.cpu': {
1574         info: 'Total CPU utilization (all cores). 100% here means there is no CPU idle time at all. You can get per core usage at the <a href="#cpu">CPUs</a> section and per application usage at the <a href="#apps">Applications Monitoring</a> section.<br/>Keep an eye on <b>iowait</b> ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.<br/>Another important metric worth monitoring, is <b>softirq</b> ' + sparkline('system.cpu', 'softirq', '%') + '. A constantly high percentage of softirq may indicate network drivers issues.'
1575     },
1576
1577     'system.load': {
1578         info: 'Current system load, i.e. the number of processes using CPU or waiting for system resources (usually CPU and disk). The 3 metrics refer to 1, 5 and 15 minute averages. Linux calculates this once every 5 seconds. Netdata reads them from <code>/proc/loadavg</code>. For more information check <a href="https://en.wikipedia.org/wiki/Load_(computing)" target="_blank">this wikipedia article</a>',
1579         height: 0.7
1580     },
1581
1582     'system.io': {
1583         info: 'Total Disk I/O, for all disks, read from <code>/proc/vmstat</code>. You can get detailed information about each disk at the <a href="#disk">Disks</a> section and per application Disk usage at the <a href="#apps">Applications Monitoring</a> section.'
1584     },
1585
1586     'system.swapio': {
1587         info: 'Total Swap I/O, read from <code>/proc/vmstat</code>. (netdata measures both <code>in</code> and <code>out</code>. If either of them is not shown in the chart, it is because it is zero - you can change the page settings to always render all the available dimensions on all charts).'
1588     },
1589
1590     'system.pgfaults': {
1591         info: 'Total page faults, read from <code>/proc/vmstat</code>. <b>Major page faults</b> indicates that the system is using its swap. You can find which applications use the swap at the <a href="#apps">Applications Monitoring</a> section.'
1592     },
1593
1594     'system.entropy': {
1595         colors: '#CC22AA',
1596         info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, read from <code>/proc/sys/kernel/random/entropy_avail</code>, is like a pool of random numbers that are mainly used in cryptography. It is advised that the pool remains always <a href="https://blog.cloudflare.com/ensuring-randomness-with-linuxs-random-number-generator/" target="_blank">above 200</a>. If the pool of entropy gets empty, you risk your security to be predictable and you should install a user-space random numbers generating daemon, like <a href="http://www.issihosts.com/haveged/" target="_blank">haveged</a>, to keep the pool in healthy levels.'
1597     },
1598
1599     'system.forks': {
1600         colors: '#5555DD',
1601         info: 'The number of new processes created per second, read from <code>/proc/stat</code>.'
1602     },
1603
1604     'system.intr': {
1605         colors: '#DD5555',
1606         info: 'Total number of CPU interrupts, read from <code>/proc/stat</code>. Check <code>system.interrupts</code> that gives more detail about each interrupt and also the <a href="#cpu">CPUs</a> section where interrupts are analyzed per CPU core.'
1607     },
1608
1609     'system.interrupts': {
1610         info: 'CPU interrupts in detail, read from <code>/proc/interrupts</code>. At the <a href="#cpu">CPUs</a> section, interrupts are analyzed per CPU core.'
1611     },
1612
1613     'system.softirqs': {
1614         info: 'CPU softirqs in detail, read from <code>/proc/softirqs</code>. At the <a href="#cpu">CPUs</a> section, softirqs are analyzed per CPU core.'
1615     },
1616
1617     'system.processes': {
1618         info: 'System processes, read from <code>/proc/stat</code>. <b>Blocked</b> are processes that are willing to execute but they cannot, e.g. because they wait for disk activity.'
1619     },
1620
1621     'system.active_processes': {
1622         info: 'All system active processes, read from <code>/proc/loadavg</code>.'
1623     },
1624
1625     'system.ctxt': {
1626         info: '<a href="https://en.wikipedia.org/wiki/Context_switch" target="_blank">Context Switches</a>, read from <code>/proc/stat</code>, is the switching of the CPU from one process, task or thread to another. If there are many processes or threads willing to execute and very few CPU cores available to handle them, the system is making more context switching to balance the CPU resources among them. The whole process is computationally intensive. The more the context switches, the slower the system gets.'
1627     },
1628
1629     'system.idlejitter': {
1630         colors: '#5555AA',
1631         info: 'Idle jitter is calculated by netdata. A thread is spawned that requests to sleep for a few microseconds. When the system wakes it up, it measures how many microseconds have passed. The difference between the requested and the actual duration of the sleep, is the <b>idle jitter</b>. This number is useful in real-time environments, where CPU jitter can affect the quality of the service (like VoIP media gateways).'
1632     },
1633
1634     'system.ipv4': {
1635         info: 'Total IPv4 Traffic, read from <code>/proc/net/netstat</code>.'
1636     },
1637
1638     'system.ipv6': {
1639         info: 'Total IPv6 Traffic, read from <code>/proc/net/snmp6</code>.'
1640     },
1641
1642     'system.ram': {
1643         info: 'System memory, read from <code>/proc/meminfo</code>.'
1644     },
1645
1646     'system.swap': {
1647         info: 'System swap memory, read from <code>/proc/meminfo</code>.'
1648     },
1649
1650     // ------------------------------------------------------------------------
1651     // MEMORY
1652
1653     'mem.ksm_savings': {
1654         heads: [
1655             gaugeChart('Saved', '12%', 'savings', '#0099CC')
1656         ]
1657     },
1658
1659     'mem.ksm_ratios': {
1660         heads: [
1661             function(id) {
1662                 return  '<div data-netdata="' + id + '"'
1663                     + ' data-gauge-max-value="100"'
1664                     + ' data-chart-library="gauge"'
1665                     + ' data-title="Savings"'
1666                     + ' data-units="percentage %"'
1667                     + ' data-gauge-adjust="width"'
1668                     + ' data-width="12%"'
1669                     + ' data-before="0"'
1670                     + ' data-after="-CHART_DURATION"'
1671                     + ' data-points="CHART_DURATION"'
1672                     + ' role="application"></div>';
1673             }
1674         ]
1675     },
1676
1677     'mem.committed': {
1678         colors: NETDATA.colors[3]
1679     },
1680
1681     // ------------------------------------------------------------------------
1682     // APPS
1683
1684     'apps.cpu': {
1685         height: 2.0
1686     },
1687
1688     'apps.preads': {
1689         height: 2.0
1690     },
1691
1692     'apps.pwrites': {
1693         height: 2.0
1694     },
1695
1696     // ------------------------------------------------------------------------
1697     // USERS
1698
1699     'users.cpu': {
1700         height: 2.0
1701     },
1702
1703     'users.preads': {
1704         height: 2.0
1705     },
1706
1707     'users.pwrites': {
1708         height: 2.0
1709     },
1710
1711     // ------------------------------------------------------------------------
1712     // GROUPS
1713
1714     'groups.cpu': {
1715         height: 2.0
1716     },
1717
1718     'groups.preads': {
1719         height: 2.0
1720     },
1721
1722     'groups.pwrites': {
1723         height: 2.0
1724     },
1725
1726     // ------------------------------------------------------------------------
1727     // NETWORK QoS
1728
1729     'tc.qos': {
1730         heads: [
1731             function(id) {
1732                 if(id.match(/.*-ifb$/))
1733                     return gaugeChart('Inbound', '12%', '', '#5555AA');
1734                 else
1735                     return gaugeChart('Outbound', '12%', '', '#AA9900');
1736             }
1737         ]
1738     },
1739
1740     // ------------------------------------------------------------------------
1741     // NETWORK INTERFACES
1742
1743     'net.net': {
1744         heads: [
1745             gaugeChart('Received', '12%', 'received'),
1746             gaugeChart('Sent', '12%', 'sent')
1747         ]
1748     },
1749
1750     // ------------------------------------------------------------------------
1751     // NETFILTER
1752
1753     'netfilter.sockets': {
1754         colors: '#88AA00',
1755         heads: [
1756             gaugeChart('Active Connections', '12%', '', '#88AA00')
1757         ]
1758     },
1759
1760     'netfilter.new': {
1761         heads: [
1762             gaugeChart('New Connections', '12%', 'new', '#5555AA')
1763         ]
1764     },
1765
1766     // ------------------------------------------------------------------------
1767     // DISKS
1768
1769     'disk.util': {
1770         colors: '#FF5588',
1771         heads: [
1772             gaugeChart('Utilization', '12%', '', '#FF5588')
1773         ],
1774         info: 'Disk Utilization measures the amount of time the disk was busy with something. This is not related to its performance. 100% means that the Linux kernel always had an outstanding operation on the disk. Keep in mind that depending on the underlying technology of the disk, 100% here may or may not be an indication of congestion.'
1775     },
1776
1777     'disk.backlog': {
1778         colors: '#0099CC',
1779         info: 'Backlog is an indication of the duration of pending disk operations. On every I/O event the Linux kernel is multiplying the time spent doing I/O since the last update of this field with the number of pending operations. While not accurate, this metric can provide an indication of the expected completion time of the operations in progress.'
1780     },
1781
1782     'disk.io': {
1783         heads: [
1784             gaugeChart('Read', '12%', 'reads'),
1785             gaugeChart('Write', '12%', 'writes')
1786         ],
1787         info: 'Amount of data transferred to and from disk.'
1788     },
1789
1790     'disk.ops': {
1791         info: 'Completed disk I/O operations. Keep in mind the number of operations requested might be higher, since the Linux kernel is able to merge adjacent to each other (see merged operations chart).'
1792     },
1793
1794     'disk.qops': {
1795         info: 'I/O operations currently in progress. This metric is a snapshot - it is not an average over the last interval.'
1796     },
1797
1798     'disk.iotime': {
1799         height: 0.5,
1800         info: 'The sum of the duration of all completed I/O operations. This number can exceed the interval if the disk is able to execute I/O operations in parallel.'
1801     },
1802     'disk.mops': {
1803         height: 0.5,
1804         info: 'The number of merged disk operations. The Linux kernel is able to merge adjacent I/O operations, for example two 4KB reads can become one 8KB read before given to disk.'
1805     },
1806     'disk.svctm': {
1807         height: 0.5,
1808         info: 'The average service time for completed I/O operations. This metric is calculated using the total busy time of the disk and the number of completed operations. If the disk is able to execute multiple parallel operations the reporting average service time will be misleading.'
1809     },
1810     'disk.avgsz': {
1811         height: 0.5,
1812         info: 'The average I/O operation size.'
1813     },
1814     'disk.await': {
1815         height: 0.5,
1816         info: 'The average time for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.'
1817     },
1818
1819     'disk.space': {
1820         info: 'Disk space utilization. reserved for root is automatically reserved by the system to prevent the root user from getting out of space.'
1821     },
1822     'disk.inodes': {
1823         info: 'inodes (or index nodes) are filesystem objects (e.g. files and directories). On many types of file system implementations, the maximum number of inodes is fixed at filesystem creation, limiting the maximum number of files the filesystem can hold. It is possible for a device to run out of inodes. When this happens, new files cannot be created on the device, even though there may be free space available.'
1824     },
1825
1826     'mysql.net': {
1827         info: 'The amount of data sent to mysql clients (<strong>out</strong>) and received from mysql clients (<strong>in</strong>).'
1828     },
1829
1830     // ------------------------------------------------------------------------
1831     // MYSQL
1832
1833     'mysql.queries': {
1834         info: 'The number of statements executed by the server.<ul>' +
1835         '<li><strong>queries</strong> counts the statements executed within stored SQL programs.</li>' +
1836         '<li><strong>questions</strong> counts the statements sent to the mysql server by mysql clients.</li>' +
1837         '<li><strong>slow queries</strong> counts the number of statements that took more than <a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_long_query_time" target="_blank">long_query_time</a> seconds to be executed.' +
1838         ' For more information about slow queries check the mysql <a href="http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html" target="_blank">slow query log</a>.</li>' +
1839         '</ul>'
1840     },
1841
1842     'mysql.handlers': {
1843         info: 'Usage of the internal handlers of mysql. This chart provides very good insights of what the mysql server is actually doing.' +
1844         ' (if the chart is not showing all these dimensions it is because they are zero - set <strong>Which dimensions to show?</strong> to <strong>All</strong> from the dashboard settings, to render even the zero values)<ul>' +
1845         '<li><strong>commit</strong>, the number of internal <a href="http://dev.mysql.com/doc/refman/5.7/en/commit.html" target="_blank">COMMIT</a> statements.</li>' +
1846         '<li><strong>delete</strong>, the number of times that rows have been deleted from tables.</li>' +
1847         '<li><strong>prepare</strong>, a counter for the prepare phase of two-phase commit operations.</li>' +
1848         '<li><strong>read first</strong>, the number of times the first entry in an index was read. A high value suggests that the server is doing a lot of full index scans; e.g. <strong>SELECT col1 FROM foo</strong>, with col1 indexed.</li>' +
1849         '<li><strong>read key</strong>, the number of requests to read a row based on a key. If this value is high, it is a good indication that your tables are properly indexed for your queries.</li>' +
1850         '<li><strong>read next</strong>, the number of requests to read the next row in key order. This value is incremented if you are querying an index column with a range constraint or if you are doing an index scan.</li>' +
1851         '<li><strong>read prev</strong>, the number of requests to read the previous row in key order. This read method is mainly used to optimize <strong>ORDER BY ... DESC</strong>.</li>' +
1852         '<li><strong>read rnd</strong>, the number of requests to read a row based on a fixed position. A high value indicates you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.</li>' +
1853         '<li><strong>read rnd next</strong>, the number of requests to read the next row in the data file. This value is high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have.</li>' +
1854         '<li><strong>rollback</strong>, the number of requests for a storage engine to perform a rollback operation.</li>' +
1855         '<li><strong>savepoint</strong>, the number of requests for a storage engine to place a savepoint.</li>' +
1856         '<li><strong>savepoint rollback</strong>, the number of requests for a storage engine to roll back to a savepoint.</li>' +
1857         '<li><strong>update</strong>, the number of requests to update a row in a table.</li>' +
1858         '<li><strong>write</strong>, the number of requests to insert a row in a table.</li>' +
1859         '</ul>'
1860     },
1861
1862     'mysql.table_locks': {
1863         info: 'MySQL table locks counters: <ul>' +
1864         '<li><strong>immediate</strong>, the number of times that a request for a table lock could be granted immediately.</li>' +
1865         '<li><strong>waited</strong>, the number of times that a request for a table lock could not be granted immediately and a wait was needed. If this is high and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication.</li>' +
1866         '</ul>'
1867     },
1868
1869     // ------------------------------------------------------------------------
1870     // APACHE
1871
1872     'apache.connections': {
1873         colors: NETDATA.colors[4],
1874         mainheads: [
1875             gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1876         ]
1877     },
1878
1879     'apache.requests': {
1880         colors: NETDATA.colors[0],
1881         mainheads: [
1882             gaugeChart('Requests', '12%', '', NETDATA.colors[0])
1883         ]
1884     },
1885
1886     'apache.net': {
1887         colors: NETDATA.colors[3],
1888         mainheads: [
1889             gaugeChart('Bandwidth', '12%', '', NETDATA.colors[3])
1890         ]
1891     },
1892
1893     'apache.workers': {
1894         mainheads: [
1895             function(id) {
1896                 return  '<div data-netdata="' + id + '"'
1897                     + ' data-dimensions="busy"'
1898                     + ' data-append-options="percentage"'
1899                     + ' data-gauge-max-value="100"'
1900                     + ' data-chart-library="gauge"'
1901                     + ' data-title="Workers Utilization"'
1902                     + ' data-units="percentage %"'
1903                     + ' data-gauge-adjust="width"'
1904                     + ' data-width="12%"'
1905                     + ' data-before="0"'
1906                     + ' data-after="-CHART_DURATION"'
1907                     + ' data-points="CHART_DURATION"'
1908                     + ' role="application"></div>';
1909             }
1910         ]
1911     },
1912
1913     'apache.bytesperreq': {
1914         colors: NETDATA.colors[3],
1915         height: 0.5
1916     },
1917
1918     'apache.reqpersec': {
1919         colors: NETDATA.colors[4],
1920         height: 0.5
1921     },
1922
1923     'apache.bytespersec': {
1924         colors: NETDATA.colors[6],
1925         height: 0.5
1926     },
1927
1928
1929     // ------------------------------------------------------------------------
1930     // NGINX
1931
1932     'nginx.connections': {
1933         colors: NETDATA.colors[4],
1934         mainheads: [
1935             gaugeChart('Connections', '12%', '', NETDATA.colors[4])
1936         ]
1937     },
1938
1939     'nginx.requests': {
1940         colors: NETDATA.colors[0],
1941         mainheads: [
1942             gaugeChart('Requests', '12%', '', NETDATA.colors[0])
1943         ]
1944     },
1945
1946     // ------------------------------------------------------------------------
1947     // NETDATA
1948
1949     'netdata.response_time': {
1950         info: 'The netdata API response time measures the time netdata needed to serve requests. This time includes everything, from the reception of the first byte of a request, to the dispatch of the last byte of its reply, therefore it includes all network latencies involved (i.e. a client over a slow network will influence these metrics).'
1951     }
1952 };
1953
1954 function anyAttribute(obj, attr, key, def) {
1955     if(typeof obj[key] !== 'undefined') {
1956         if(typeof obj[key][attr] !== 'undefined')
1957             return obj[key][attr];
1958     }
1959     return def;
1960 }
1961
1962 function menuTitle(chart) {
1963     if(typeof chart.menu_pattern !== 'undefined') {
1964         return anyAttribute(menuData, 'title', chart.menu_pattern, chart.menu_pattern).toString()
1965                 + ': ' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString();
1966     }
1967
1968     return anyAttribute(menuData, 'title', chart.menu, chart.menu);
1969 }
1970
1971 function menuInfo(menu) {
1972     return anyAttribute(menuData, 'info', menu, null);
1973 }
1974
1975 function menuHeight(menu, relative) {
1976     return anyAttribute(menuData, 'height', menu, 1.0) * relative;
1977 }
1978
1979 function submenuTitle(menu, submenu) {
1980     var key = menu + '.' + submenu;
1981     return anyAttribute(submenuData, 'title', key, submenu);
1982 }
1983
1984 function submenuInfo(menu, submenu) {
1985     var key = menu + '.' + submenu;
1986     return anyAttribute(submenuData, 'info', key, null);
1987 }
1988
1989 function submenuHeight(menu, submenu, relative) {
1990     var key = menu + '.' + submenu;
1991     return anyAttribute(submenuData, 'height', key, 1.0) * relative;
1992 }
1993
1994
1995 function chartInfo(id) {
1996     if(typeof chartData[id] !== 'undefined' && typeof chartData[id].info !== 'undefined')
1997         return '<div class="chart-message netdata-chart-alignment" role="document">' + chartData[id].info + '</div>';
1998     else
1999         return '';
2000 }
2001
2002 function chartHeight(id, def) {
2003     if(typeof chartData[id] !== 'undefined' && typeof chartData[id].height !== 'undefined')
2004         return def * chartData[id].height;
2005     else
2006         return def;
2007 }
2008
2009
2010 // ----------------------------------------------------------------------------
2011
2012 // enrich the data structure returned by netdata
2013 // to reflect our menu system and content
2014 function enrichChartData(chart) {
2015     var tmp = chart.type.split('_')[0];
2016
2017     switch(tmp) {
2018         case 'ap':
2019         case 'net':
2020         case 'disk':
2021             chart.menu = tmp;
2022             break;
2023
2024         case 'cgroup':
2025             chart.menu = chart.type;
2026             if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
2027                 chart.menu_pattern = 'cgqemu';
2028             else
2029                 chart.menu_pattern = 'cgroup';
2030             break;
2031
2032         case 'apache':
2033         case 'exim':
2034         case 'memcached':
2035         case 'mysql':
2036         case 'named':
2037         case 'nginx':
2038         case 'phpfpm':
2039         case 'postfix':
2040         case 'redis':
2041         case 'ipfs':
2042         case 'squid':
2043         case 'snmp':
2044         case 'tomcat':
2045             chart.menu = chart.type;
2046             chart.menu_pattern = tmp;
2047             break;
2048
2049         case 'tc':
2050             chart.menu = tmp;
2051
2052             // find a name for this device from fireqos info
2053             // we strip '_(in|out)' or '(in|out)_'
2054             if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
2055                 var n = chart.name.split('.')[1];
2056                 if(n.endsWith('_in'))
2057                     options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
2058                 else if(n.endsWith('_out'))
2059                     options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
2060                 else if(n.startsWith('in_'))
2061                     options.submenu_names[chart.family] = n.slice(3, n.length);
2062                 else if(n.startsWith('out_'))
2063                     options.submenu_names[chart.family] = n.slice(4, n.length);
2064             }
2065
2066             // increase the priority of IFB devices
2067             // to have inbound appear before outbound
2068             if(chart.id.match(/.*-ifb$/))
2069                 chart.priority--;
2070
2071             break;
2072
2073         default:
2074             chart.menu = chart.type;
2075             break;
2076     }
2077
2078     chart.submenu = chart.family;
2079 }
2080
2081 // ----------------------------------------------------------------------------
2082
2083 function name2id(s) {
2084     return s
2085         .replace(/ /g, '_')
2086         .replace(/\(/g, '_')
2087         .replace(/\)/g, '_')
2088         .replace(/\./g, '_')
2089         .replace(/\//g, '_');
2090 }
2091
2092 function headMain(charts, duration) {
2093     var head = '';
2094
2095     if(typeof charts['system.swap'] !== 'undefined')
2096         head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
2097         + ' data-dimensions="free"'
2098         + ' data-append-options="percentage"'
2099         + ' data-chart-library="easypiechart"'
2100         + ' data-title="Free Swap"'
2101         + ' data-units="%"'
2102         + ' data-easypiechart-max-value="100"'
2103         + ' data-width="8%"'
2104         + ' data-before="0"'
2105         + ' data-after="-' + duration.toString() + '"'
2106         + ' data-points="' + duration.toString() + '"'
2107         + ' data-colors="#DD4400"'
2108         + ' role="application"></div>';
2109
2110     if(typeof charts['system.io'] !== 'undefined') {
2111         head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2112         + ' data-dimensions="in"'
2113         + ' data-chart-library="easypiechart"'
2114         + ' data-title="Disk Read"'
2115         + ' data-width="10%"'
2116         + ' data-before="0"'
2117         + ' data-after="-' + duration.toString() + '"'
2118         + ' data-points="' + duration.toString() + '"'
2119         + ' role="application"></div>';
2120
2121         head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2122         + ' data-dimensions="out"'
2123         + ' data-chart-library="easypiechart"'
2124         + ' data-title="Disk Write"'
2125         + ' data-width="10%"'
2126         + ' data-before="0"'
2127         + ' data-after="-' + duration.toString() + '"'
2128         + ' data-points="' + duration.toString() + '"'
2129         + ' role="application"></div>';
2130     }
2131
2132     if(typeof charts['system.cpu'] !== 'undefined')
2133         head += '<div data-netdata="system.cpu"'
2134         + ' data-chart-library="gauge"'
2135         + ' data-title="CPU"'
2136         + ' data-units="%"'
2137         + ' data-gauge-max-value="100"'
2138         + ' data-width="18%"'
2139         + ' data-after="-' + duration.toString() + '"'
2140         + ' data-points="' + duration.toString() + '"'
2141         + ' data-colors="' + NETDATA.colors[12] + '"'
2142         + ' role="application"></div>';
2143
2144     if(typeof charts['system.ipv4'] !== 'undefined') {
2145         head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2146         + ' data-dimensions="received"'
2147         + ' data-chart-library="easypiechart"'
2148         + ' data-title="IPv4 Inbound"'
2149         + ' data-width="10%"'
2150         + ' data-before="0"'
2151         + ' data-after="-' + duration.toString() + '"'
2152         + ' data-points="' + duration.toString() + '"'
2153         + ' role="application"></div>';
2154
2155         head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2156         + ' data-dimensions="sent"'
2157         + ' data-chart-library="easypiechart"'
2158         + ' data-title="IPv4 Outbound"'
2159         + ' data-width="10%"'
2160         + ' data-before="0"'
2161         + ' data-after="-' + duration.toString() + '"'
2162         + ' data-points="' + duration.toString() + '"'
2163         + ' role="application"></div>';
2164     }
2165     else if(typeof charts['system.ipv6'] !== 'undefined') {
2166         head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2167         + ' data-dimensions="received"'
2168         + ' data-chart-library="easypiechart"'
2169         + ' data-title="IPv6 Inbound"'
2170         + ' data-units="kbps"'
2171         + ' data-width="10%"'
2172         + ' data-before="0"'
2173         + ' data-after="-' + duration.toString() + '"'
2174         + ' data-points="' + duration.toString() + '"'
2175         + ' role="application"></div>';
2176
2177         head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2178         + ' data-dimensions="sent"'
2179         + ' data-chart-library="easypiechart"'
2180         + ' data-title="IPv6 Outbound"'
2181         + ' data-units="kbps"'
2182         + ' data-width="10%"'
2183         + ' data-before="0"'
2184         + ' data-after="-' + duration.toString() + '"'
2185         + ' data-points="' + duration.toString() + '"'
2186         + ' role="application"></div>';
2187     }
2188
2189     if(typeof charts['system.ram'] !== 'undefined')
2190         head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
2191         + ' data-dimensions="cached|free"'
2192         + ' data-append-options="percentage"'
2193         + ' data-chart-library="easypiechart"'
2194         + ' data-title="Available RAM"'
2195         + ' data-units="%"'
2196         + ' data-easypiechart-max-value="100"'
2197         + ' data-width="8%"'
2198         + ' data-after="-' + duration.toString() + '"'
2199         + ' data-points="' + duration.toString() + '"'
2200         + ' data-colors="' + NETDATA.colors[7] + '"'
2201         + ' role="application"></div>';
2202
2203     return head;
2204 }
2205
2206 function generateHeadCharts(type, chart, duration) {
2207     var head = '';
2208     var hcharts = anyAttribute(chartData, type, chart.context, []);
2209     if(hcharts.length > 0) {
2210         var hi = 0, hlen = hcharts.length;
2211         while(hi < hlen) {
2212             if(typeof hcharts[hi] === 'function')
2213                 head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2214             else
2215                 head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2216             hi++;
2217         }
2218     }
2219     return head;
2220 }
2221
2222 function renderPage(menus, data) {
2223     var div = document.getElementById('charts_div');
2224     var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
2225
2226     // find the proper duration for per-second updates
2227     var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
2228     var html = '';
2229     var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
2230     var mainhead = headMain(data.charts, duration);
2231
2232     // sort the menus
2233     var main = sortObjectByPriority(menus);
2234     var i = 0, len = main.length;
2235     while(i < len) {
2236         var menu = main[i++];
2237
2238         // generate an entry at the main menu
2239
2240         var menuid = name2id(menu);
2241         sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].title + '</a><ul class="nav">';
2242         html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div id="menu_' + menuid + '" role="document">';
2243
2244         if(menus[menu].info !== null)
2245             html += menus[menu].info;
2246
2247         // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
2248
2249         var shtml = '';
2250         var mhead = '<div class="netdata-chart-row">' + mainhead;
2251         mainhead = '';
2252
2253         // sort the submenus of this menu
2254         var sub = sortObjectByPriority(menus[menu].submenus);
2255         var si = 0, slen = sub.length;
2256         while(si < slen) {
2257             var submenu = sub[si++];
2258
2259             // generate an entry at the submenu
2260             var submenuid = name2id(menu + '_' + submenu);
2261             sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
2262             shtml += '<div class="netdata-group-container" id="submenu_' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
2263
2264             if(menus[menu].submenus[submenu].info !== null)
2265                 shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
2266
2267             var head = '<div class="netdata-chart-row">';
2268             var chtml = '';
2269
2270             // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
2271
2272             // sort the charts in this submenu of this menu
2273             menus[menu].submenus[submenu].charts.sort(prioritySort);
2274             var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
2275             while(ci < clen) {
2276                 var chart = menus[menu].submenus[submenu].charts[ci++];
2277
2278                 // generate the submenu heading charts
2279                 mhead += generateHeadCharts('mainheads', chart, duration);
2280                 head += generateHeadCharts('heads', chart, duration);
2281
2282                 // generate the chart
2283                 chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
2284                     + ' data-width="' + pcent_width.toString() + '%"'
2285                     + ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
2286                     + ' data-before="0"'
2287                     + ' data-after="-' + duration.toString() + '"'
2288                     + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
2289                     + ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
2290                     + ' role="application"></div>';
2291
2292                 // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
2293             }
2294
2295             head += '</div>';
2296             shtml += head + chtml + '</div>';
2297         }
2298
2299         mhead += '</div>';
2300         sidebar += '</ul></li>';
2301         html += mhead + shtml + '</div></div><hr role="separator"/>';
2302     }
2303
2304     sidebar += '</ul>';
2305     div.innerHTML = html;
2306     document.getElementById('sidebar').innerHTML = sidebar;
2307     finalizePage();
2308 }
2309
2310 function renderChartsAndMenu(data) {
2311     var menus = {};
2312     var charts = data.charts;
2313
2314     for(var c in charts) {
2315         enrichChartData(charts[c]);
2316
2317         // create the menu
2318         if(typeof menus[charts[c].menu] === 'undefined') {
2319             menus[charts[c].menu] = {
2320                 priority: charts[c].priority,
2321                 submenus: {},
2322                 title: menuTitle(charts[c]),
2323                 info: menuInfo(charts[c].menu),
2324                 height: menuHeight(charts[c].menu, options.chartsHeight)
2325             };
2326         }
2327
2328         if(charts[c].priority < menus[charts[c].menu].priority)
2329             menus[charts[c].menu].priority = charts[c].priority;
2330
2331         // create the submenu
2332         if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
2333             menus[charts[c].menu].submenus[charts[c].submenu] = {
2334                 priority: charts[c].priority,
2335                 charts: new Array(),
2336                 title: null,
2337                 info: submenuInfo(charts[c].menu, charts[c].submenu),
2338                 height: submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
2339             };
2340         }
2341
2342         if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
2343             menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
2344
2345         // index the chart in the menu/submenu
2346         menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
2347     }
2348
2349     // propagate the descriptive subname given to QoS
2350     // to all the other submenus with the same name
2351     for(var m in menus) {
2352         for(var s in menus[m].submenus) {
2353             // set the family using a name
2354             if(typeof options.submenu_names[s] !== 'undefined') {
2355                 menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
2356             }
2357             else {
2358                 menus[m].submenus[s].title = submenuTitle(m, s);
2359             }
2360         }
2361     }
2362
2363     renderPage(menus, data);
2364 }
2365
2366 function downloadAllCharts(netdata_url) {
2367     if(typeof netdata_url === 'undefined' || netdata_url === null)
2368         netdata_url = NETDATA.serverDefault;
2369
2370     NETDATA.pause(function() {
2371         $("#loadOverlay").css("display","none");
2372         $("#loadOverlay").css("display","none");
2373
2374         // download all the charts the server knows
2375         NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
2376
2377             options.data = data;
2378             options.hostname = data.hostname;
2379             document.getElementById('hostname').innerHTML = options.hostname;
2380             document.getElementById('hostname').href = NETDATA.serverDefault;
2381             document.title = options.hostname + ' netdata dashboard';
2382
2383             renderChartsAndMenu(data);
2384
2385             // prepare our DOM
2386 //          prepareScreen(data);
2387
2388             // due to affix issues, prepareScreen() will unpause
2389             // netdata as needed
2390         });
2391     });
2392 }
2393
2394 // ----------------------------------------------------------------------------
2395
2396 function versionLog(msg) {
2397     document.getElementById('versionCheckLog').innerHTML = msg;
2398 }
2399
2400 function getNetdataVersion(callback) {
2401     versionLog('Downloading installed version info from netdata...');
2402
2403     $.ajax({
2404         url: 'version.txt',
2405         async: true,
2406         cache: false
2407     })
2408     .done(function(data) {
2409         data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
2410         if(data.length !== 40) {
2411             versionLog('Received version string is invalid.');
2412             callback(null);
2413         }
2414         else {
2415             versionLog('Installed version of netdata is ' + data);
2416             document.getElementById('netdataVersion').innerHTML = data;
2417             callback(data);
2418         }
2419     })
2420     .fail(function() {
2421         versionLog('Failed to download installed version info from netdata!');
2422         callback(null);
2423     });
2424 }
2425
2426 function getGithubLatestCommit(callback) {
2427     versionLog('Downloading latest version info from github...');
2428
2429     $.ajax({
2430         url: 'https://api.github.com/repos/firehol/netdata/commits',
2431         async: true,
2432         cache: false
2433     })
2434     .done(function(data) {
2435         versionLog('Latest version info from github is ' + data[0].sha);
2436         callback(data[0].sha);
2437     })
2438     .fail(function() {
2439         versionLog('Failed to download installed version info from github!');
2440         callback(null);
2441     });
2442 }
2443
2444 function checkForUpdate(callback) {
2445     getNetdataVersion(function(sha1) {
2446         if(sha1 === null) callback(null, null);
2447
2448         getGithubLatestCommit(function(sha2) {
2449             callback(sha1, sha2);
2450         });
2451     });
2452
2453     return null;
2454 }
2455
2456 var updateBlinkCounter = 0;
2457 function notifyForUpdate(force) {
2458     versionLog('<p>checking for updates...</p>');
2459
2460     var now = new Date().getTime();
2461
2462     if(typeof force === 'undefined' || force !== true) {
2463         var last = loadLocalStorage('last_update_check');
2464
2465         if(typeof last === 'string')
2466             last = parseInt(last);
2467         else
2468             last = 0;
2469
2470         if(now - last < 3600000 * 8) {
2471             // no need to check it - too soon
2472             return;
2473         }
2474     }
2475
2476     checkForUpdate(function(sha1, sha2) {
2477         var save = false;
2478
2479         if(sha1 === null) {
2480             save = false;
2481             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>');
2482         }
2483         else if(sha2 === null) {
2484             save = false;
2485             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>');
2486         }
2487         else if(sha1 === sha2) {
2488             save = true;
2489             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>');
2490         }
2491         else {
2492             save = true;
2493             var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
2494
2495             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>');
2496
2497             function updateButtonBlink() {
2498                 updateBlinkCounter--;
2499                 if(updateBlinkCounter > 0)
2500                     $('#updateButton').fadeOut(500).fadeIn(500, updateButtonBlink);
2501             }
2502
2503             if(updateBlinkCounter === 0) {
2504                 updateBlinkCounter = 300;
2505                 updateButtonBlink();
2506             }
2507         }
2508
2509         if(save)
2510             saveLocalStorage('last_update_check', now.toString());
2511     });
2512 }
2513
2514 // ----------------------------------------------------------------------------
2515
2516 function finalizePage() {
2517     // resize all charts - without starting the background thread
2518     // this has to be done while NETDATA is paused
2519     // if we ommit this, the affix menu will be wrong, since all
2520     // the Dom elements are initially zero-sized
2521     NETDATA.parseDom();
2522
2523     if(urlOptions.pan_and_zoom === true) {
2524         urlOptions.nowelcome = true;
2525         NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
2526     }
2527
2528     // ------------------------------------------------------------------------
2529     // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
2530     $.fn.shorten = function(settings) {
2531         "use strict";
2532
2533         var config = {
2534             showChars: 750,
2535             minHideChars: 10,
2536             ellipsesText: "...",
2537             moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
2538             lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
2539             onLess: function() { NETDATA.onscroll(); },
2540             onMore: function() { NETDATA.onscroll(); },
2541             errMsg: null,
2542             force: false
2543         };
2544
2545         if (settings) {
2546             $.extend(config, settings);
2547         }
2548
2549         if ($(this).data('jquery.shorten') && !config.force) {
2550             return false;
2551         }
2552         $(this).data('jquery.shorten', true);
2553
2554         $(document).off("click", '.morelink');
2555
2556         $(document).on({
2557             click: function() {
2558
2559                 var $this = $(this);
2560                 if ($this.hasClass('less')) {
2561                     $this.removeClass('less');
2562                     $this.html(config.moreText);
2563                     $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
2564                         config.onLess();
2565                     });
2566
2567                 } else {
2568                     $this.addClass('less');
2569                     $this.html(config.lessText);
2570                     $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
2571                         config.onMore();
2572                     });
2573                 }
2574                 return false;
2575             }
2576         }, '.morelink');
2577
2578         return this.each(function() {
2579             var $this = $(this);
2580
2581             var content = $this.html();
2582             var contentlen = $this.text().length;
2583             if (contentlen > config.showChars + config.minHideChars) {
2584                 var c = content.substr(0, config.showChars);
2585                 if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
2586                 {
2587                     var inTag = false; // I'm in a tag?
2588                     var bag = ''; // Put the characters to be shown here
2589                     var countChars = 0; // Current bag size
2590                     var openTags = []; // Stack for opened tags, so I can close them later
2591                     var tagName = null;
2592
2593                     for (var i = 0, r = 0; r <= config.showChars; i++) {
2594                         if (content[i] == '<' && !inTag) {
2595                             inTag = true;
2596
2597                             // This could be "tag" or "/tag"
2598                             tagName = content.substring(i + 1, content.indexOf('>', i));
2599
2600                             // If its a closing tag
2601                             if (tagName[0] == '/') {
2602
2603
2604                                 if (tagName != '/' + openTags[0]) {
2605                                     config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
2606                                 } else {
2607                                     openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
2608                                 }
2609
2610                             } else {
2611                                 // There are some nasty tags that don't have a close tag like <br/>
2612                                 if (tagName.toLowerCase() != 'br') {
2613                                     openTags.unshift(tagName); // Add to start the name of the tag that opens
2614                                 }
2615                             }
2616                         }
2617                         if (inTag && content[i] == '>') {
2618                             inTag = false;
2619                         }
2620
2621                         if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
2622                         else {
2623                             r++;
2624                             if (countChars <= config.showChars) {
2625                                 bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
2626                                 countChars++;
2627                             } else // Now I have the characters needed
2628                             {
2629                                 if (openTags.length > 0) // I have unclosed tags
2630                                 {
2631                                     //console.log('They were open tags');
2632                                     //console.log(openTags);
2633                                     for (j = 0; j < openTags.length; j++) {
2634                                         //console.log('Cierro tag ' + openTags[j]);
2635                                         bag += '</' + openTags[j] + '>'; // Close all tags that were opened
2636
2637                                         // 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
2638                                     }
2639                                     break;
2640                                 }
2641                             }
2642                         }
2643                     }
2644                     c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
2645                 }else{
2646                     c+=config.ellipsesText;
2647                 }
2648
2649                 var html = '<div class="shortcontent">' + c +
2650                         '</div><div class="allcontent">' + content +
2651                         '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
2652
2653                 $this.html(html);
2654                 $this.find(".allcontent").hide(); // Hide all text
2655                 $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
2656             }
2657         });
2658
2659     };
2660     $(".chart-message").shorten();
2661     // ------------------------------------------------------------------------
2662
2663     // callback for us to track PanAndZoom operations
2664     NETDATA.globalPanAndZoom.callback = netdataPanAndZoomCallback;
2665
2666     // let it run (update the charts)
2667     NETDATA.unpause();
2668
2669     // check if we have to jump to a specific section
2670     scrollToId(urlOptions.hash.replace('#',''));
2671
2672     /* activate bootstrap sidebar (affix) */
2673     $('#sidebar').affix({
2674         offset: {
2675             top: (isdemo())?150:0,
2676             bottom: 0
2677         }
2678     });
2679
2680     /* fix scrolling of very long affix lists
2681        http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
2682      */
2683     $('#sidebar').on('affixed.bs.affix', function() {
2684         $(this).removeAttr('style');
2685     });
2686
2687     /* activate bootstrap scrollspy (needed for sidebar) */
2688     $(document.body).scrollspy({
2689         target: '#sidebar',
2690         offset: $(window).height() / 3 // controls the diff of the <hX> element to the top, to select it
2691     });
2692
2693     // change the URL based on the current position of the screen
2694     $('#sidebar').on('activate.bs.scrollspy', function (e) {
2695         var el = $(e.target);
2696         if(el.find('ul').size() == 0) {
2697             var hash = el.find('a').attr('href');
2698             if(typeof hash === 'string' && hash.substring(0, 1) == '#') {
2699                 urlOptions.hash = hash;
2700                 // console.log(urlOptions.hash);
2701                 netdataHashUpdate();
2702             }
2703         }
2704     });
2705
2706     document.getElementById('footer').style.display = 'block';
2707
2708     var update_options_modal = function() {
2709         // console.log('update_options_modal');
2710
2711         var sync_option = function(option) {
2712             var self = $('#' + option);
2713
2714             if(self.prop('checked') !== NETDATA.getOption(option)) {
2715                 // console.log('switching ' + option.toString());
2716                 self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
2717             }
2718         }
2719
2720         var theme_sync_option = function(option) {
2721             var self = $('#' + option);
2722
2723             self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
2724         }
2725
2726         sync_option('eliminate_zero_dimensions');
2727         sync_option('destroy_on_hide');
2728         sync_option('parallel_refresher');
2729         sync_option('concurrent_refreshes');
2730         sync_option('sync_selection');
2731         sync_option('sync_pan_and_zoom');
2732         sync_option('stop_updates_when_focus_is_lost');
2733         sync_option('smooth_plot');
2734         sync_option('pan_and_zoom_data_padding');
2735         sync_option('show_help');
2736         theme_sync_option('netdata_theme_control');
2737
2738         if(NETDATA.getOption('parallel_refresher') === false) {
2739             $('#concurrent_refreshes_row').hide();
2740         }
2741         else {
2742             $('#concurrent_refreshes_row').show();
2743         }
2744     };
2745     NETDATA.setOption('setOptionCallback', update_options_modal);
2746
2747     // handle options changes
2748     $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
2749     $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
2750     $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
2751     $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
2752     $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
2753     $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
2754     $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
2755     $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
2756     $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
2757     $('#show_help').change(function()                       {
2758         urlOptions.help = $(this).prop('checked');
2759         NETDATA.setOption('show_help', urlOptions.help);
2760         netdataReload();
2761     });
2762
2763     // this has to be the last
2764     // it reloads the page
2765     $('#netdata_theme_control').change(function() {
2766         urlOptions.theme = $(this).prop('checked')?'slate':'white';
2767         if(setTheme(urlOptions.theme))
2768             netdataReload();
2769     });
2770
2771     $('#updateModal').on('shown.bs.modal', function() {
2772         notifyForUpdate(true);
2773     });
2774
2775     $('#deleteRegistryModal').on('hidden.bs.modal', function() {
2776         deleteRegistryGuid = null;
2777     });
2778
2779     if(isdemo()) {
2780         if(!urlOptions.nowelcome) {
2781             setTimeout(function() {
2782                 $('#welcomeModal').modal();
2783             }, 1000);
2784         }
2785
2786         // google analytics when this is used for the home page of the demo sites
2787         // this does not run on user's installations
2788         setTimeout(function() {
2789             (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
2790             (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
2791             m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
2792             })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
2793
2794             ga('create', 'UA-64295674-3', 'auto');
2795             ga('send', 'pageview');
2796         }, 2000);
2797     }
2798     else notifyForUpdate();
2799 }
2800
2801 function resetDashboardOptions() {
2802     var help = NETDATA.options.current.show_help;
2803
2804     NETDATA.resetOptions();
2805     if(setTheme('slate'))
2806         netdataReload();
2807
2808     if(help !== NETDATA.options.current.show_help)
2809         netdataReload();
2810 }
2811
2812 downloadAllCharts();
2813
2814 </script>
2815
2816 </body>
2817 </html>