]> arthur.barton.de Git - netdata.git/blob - web/index.html
lookup all the known URLs of a machine
[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     /* prevent body from hiding under the navbar */
40     body {
41         padding-top: 50px;
42     }
43
44     .loadOverlay {
45         position: absolute;
46         top: 0px;
47         left: 0px;
48         width: 100%;
49         height:100%;
50         z-index: 2000;
51         font-size: 10vh;
52         font-family: sans-serif;
53         padding: 40vh 0 40vh 0;
54         font-weight: bold;
55         text-align: center;
56     }
57
58     .modal-wide .modal-dialog {
59         width: 80%;
60     }
61
62     /* fix # anchors scrolling under the navbar
63        https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
64      */
65     h1 {
66         position: relative;
67         z-index: -1;
68     }
69     h2 {
70         position: relative;
71         z-index: -2;
72     }
73     h1:before, h2:before {
74         display: block;
75         content: " ";
76         margin-top: -70px;
77         height: 70px;
78         visibility: hidden;
79     }
80
81     .p {
82         display: block;
83         margin-top: 15px;
84     }
85
86     .option-row,
87     .option-control {
88         vertical-align: top;
89         padding: 10px;
90         padding-top: 30px;
91         padding-left: 30px;
92     }
93
94     .option-info {
95         padding: 10px;
96     }
97
98     .chart-message {
99         display: block;
100         margin-top: 10px;
101     }
102
103     #masthead h1 {
104         /*font-size: 30px;*/
105         line-height: 1;
106         padding-top: 30px;
107     }
108
109     #masthead .well {
110         margin-top:4%;
111     }
112
113     /* fix the navbar shifting when a modal is open */
114     /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
115     body.modal-open{
116         width: 100% !important;
117         padding-right: 0 !important;
118 /*      overflow-y: scroll !important; */
119 /*      position: fixed !important;*/
120         overflow: visible;
121     }
122
123     /* make accordion use the whole header bar for expand/collapse */
124     .panel-title a {
125         display: block;
126         padding: 10px 15px;
127         margin: -10px -15px;
128     }
129
130     /*
131      * Side navigation
132      *
133      * Scrollspy and affixed enhanced navigation to highlight sections and secondary
134      * sections of docs content.
135      */
136
137     .affix {
138         position: static;
139         top: 70px !important;
140         /*width: 220px;*/
141     }
142
143     .affix-top {
144         /*width: 220px;*/
145     }
146
147     .dashboard-sidebar {
148         max-height: calc(100% - 70px) !important;
149         overflow-y: auto;
150         /*width: 220px !important;*/
151     }
152
153     /* By default it's not affixed in mobile views, so undo that */
154     .dashboard-sidebar.affix {
155         position: static;
156     }
157
158     @media (min-width: 768px) {
159         .dashboard-sidebar {
160             padding-left: 20px;
161         }
162     }
163
164     /* First level of nav */
165     .dashboard-sidenav {
166         margin-top: 20px;
167         margin-bottom: 20px;
168     }
169
170     /* All levels of nav */
171     .dashboard-sidebar .nav > li > a {
172         display: block;
173         padding: 4px 20px;
174         font-size: 13px;
175         font-weight: 500;
176         color: #767676;
177     }
178     .dashboard-sidebar .nav > li > a:hover,
179     .dashboard-sidebar .nav > li > a:focus {
180         padding-left: 19px;
181         color: #563d7c;
182         text-decoration: none;
183         background-color: transparent;
184         border-left: 1px solid #563d7c;
185     }
186     .dashboard-sidebar .nav > .active > a,
187     .dashboard-sidebar .nav > .active:hover > a,
188     .dashboard-sidebar .nav > .active:focus > a {
189         padding-left: 18px;
190         font-weight: bold;
191         color: #563d7c;
192         background-color: transparent;
193         border-left: 2px solid #563d7c;
194     }
195
196     /* Nav: second level (shown on .active) */
197     .dashboard-sidebar .nav .nav {
198         display: none; /* Hide by default, but at >768px, show it */
199         padding-bottom: 10px;
200     }
201     .dashboard-sidebar .nav .nav > li > a {
202         padding-top: 1px;
203         padding-bottom: 1px;
204         padding-left: 30px;
205         font-size: 12px;
206         font-weight: normal;
207     }
208     .dashboard-sidebar .nav .nav > li > a:hover,
209     .dashboard-sidebar .nav .nav > li > a:focus {
210         padding-left: 29px;
211     }
212     .dashboard-sidebar .nav .nav > .active > a,
213     .dashboard-sidebar .nav .nav > .active:hover > a,
214     .dashboard-sidebar .nav .nav > .active:focus > a {
215         padding-left: 28px;
216         font-weight: 500;
217     }
218
219     .dropdown-menu {
220         min-width: 200px;
221     }
222     .dropdown-menu.columns-2 {
223         margin: 0;
224         padding: 0;
225         width: 400px;
226     }
227     .dropdown-menu li a {
228         padding: 5px 15px;
229         font-weight: 300;
230     }
231     .dropdown-menu.multi-column {
232         overflow-x: hidden;
233     }
234     .multi-column-dropdown {
235         list-style: none;
236         padding: 0;
237     }
238     .multi-column-dropdown li a {
239         display: block;
240         clear: both;
241         line-height: 1.428571429;
242         white-space: normal;
243     }
244     .multi-column-dropdown li a:hover {
245         text-decoration: none;
246         color: #f5f5f5;
247         background-color: #262626;
248     }
249     .scrollable-menu {
250         height: auto;
251         max-height: 80vh;
252         overflow-x: hidden;
253     }
254
255     /* Back to top (hidden on mobile) */
256     .back-to-top,
257     .dashboard-theme-toggle {
258         display: none;
259         padding: 4px 10px;
260         margin-top: 10px;
261         margin-left: 10px;
262         font-size: 12px;
263         font-weight: 500;
264         color: #999;
265     }
266     .back-to-top:hover,
267     .dashboard-theme-toggle:hover {
268         color: #563d7c;
269         text-decoration: none;
270     }
271     .dashboard-theme-toggle {
272         margin-top: 0;
273     }
274
275     .container {
276         width: calc(100% - 20px) !important;
277     }
278
279     .charts-body {
280         display: inline-block;
281         width: 100%;
282     }
283
284     .sidebar-body {
285         position: absolute;
286         display: none;
287     }
288
289     @media (min-width: 768px) {
290         .charts-body {
291             padding-left: 0%;
292             padding-right: 0%;
293         }
294
295         .back-to-top,
296         .dashboard-theme-toggle {
297             display: block;
298         }
299     }
300
301     /* Show and affix the side nav when space allows it */
302     @media (min-width: 992px) {
303         .container {
304             padding-left: 0% !important;
305         }
306
307         .charts-body {
308             width: calc(100% - 213px) !important;
309             padding-left: 1% !important;
310             padding-right: 0% !important;
311         }
312
313         .sidebar-body {
314             display: inline-block !important;
315             width: 213px !important;
316         }
317
318         .dashboard-sidebar .nav > .active > ul {
319             display: block;
320         }
321
322         /* Widen the fixed sidebar */
323         .dashboard-sidebar.affix,
324         .dashboard-sidebar.affix-top,
325         .dashboard-sidebar.affix-bottom {
326             width: 213px !important;
327         }
328         .dashboard-sidebar.affix {
329             position: fixed; /* Undo the static from mobile first approach */
330             top: 20px;
331         }
332         .dashboard-sidebar.affix-bottom {
333             position: absolute; /* Undo the static from mobile first approach */
334         }
335         .dashboard-sidebar.affix-bottom .dashboard-sidenav,
336         .dashboard-sidebar.affix .dashboard-sidenav {
337             margin-top: 0;
338             margin-bottom: 0;
339         }
340     }
341
342     @media (min-width: 1200px) {
343         .container {
344             padding-left: 2% !important;
345         }
346
347         .charts-body {
348             width: calc(100% - 233px) !important;
349             padding-left: 1% !important;
350             padding-right: 1% !important;
351         }
352
353         .sidebar-body {
354             display: inline-block !important;
355             width: 233px !important;
356         }
357
358         /* Widen the fixed sidebar again */
359         .dashboard-sidebar.affix,
360         .dashboard-sidebar.affix-top,
361         .dashboard-sidebar.affix-bottom {
362             width: 233px !important;
363         }
364     }
365     
366     @media (min-width: 1360px) {
367         .container {
368             padding-left: 3% !important;
369         }
370
371         .charts-body {
372             width: calc(100% - 263px) !important;
373             padding-left: 1% !important;
374             padding-right: 2% !important;
375         }
376
377         .sidebar-body {
378             display: inline-block !important;
379             width: 263px !important;
380         }
381
382         /* Widen the fixed sidebar again */
383         .dashboard-sidebar.affix,
384         .dashboard-sidebar.affix-top,
385         .dashboard-sidebar.affix-bottom {
386             width: 263px !important;
387         }
388     }
389
390     </style>
391 </head>
392
393 <!-- check which theme to use -->
394 <script type="text/javascript">
395     // enable alarms checking and notifications
396     var netdataShowAlarms = true;
397
398     // enable registry updates
399     var netdataRegistry = true;
400     
401     // --------------------------------------------------------------------
402     // urlOptions
403
404     var urlOptions = {
405         hash: '#',
406         theme: null,
407         help: null,
408         pan_and_zoom: false,
409         after: 0,
410         before: 0,
411         nowelcome: false,
412         show_alarms: false,
413         chart: null,
414         family: null,
415         alarm: null,
416         alarm_unique_id: 0,
417         alarm_id: 0,
418         alarm_event_id: 0,
419         hasProperty: function(property) {
420             // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
421             return typeof this[property] !== 'undefined';
422         }
423     };
424
425     function netdataPanAndZoomCallback(status, after, before) {
426         urlOptions.pan_and_zoom = status;
427         urlOptions.after = after;
428         urlOptions.before = before;
429         netdataHashUpdate();
430     }
431
432     function netdataHashUpdate() {
433         history.replaceState(null, '', netdataHash());
434     }
435
436     function netdataHash() {
437         var hash = urlOptions.hash;
438
439         if(urlOptions.pan_and_zoom === true) {
440             hash += ';after='  + urlOptions.after.toString() +
441                     ';before=' + urlOptions.before.toString();
442         }
443
444         if(urlOptions.theme !== null)
445             hash += ';theme=' + urlOptions.theme.toString();
446
447         if(urlOptions.help !== null)
448             hash += ';help=' + urlOptions.help.toString();
449
450         return hash;
451     }
452
453     function netdataHashParse() {
454         var variables = document.location.hash.split(';');
455         var len = variables.length;
456         while(len--) {
457             if(len !== 0) {
458                 var p = variables[len].split('=');
459                 if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
460                     urlOptions[p[0]] = decodeURIComponent(p[1]);
461             }
462             else {
463                 if(variables[len].length > 0)
464                     urlOptions.hash = variables[len];
465             }
466         }
467
468         var booleans = [ 'nowelcome', 'show_alarms', 'pan_and_zoom' ];
469         len = booleans.length;
470         while(len--) {
471             if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1)
472                 urlOptions[booleans[len]] = true;
473             else
474                 urlOptions[booleans[len]] = false;
475         }
476
477         if(urlOptions.before > 0 && urlOptions.after > 0) {
478             urlOptions.pan_and_zoom = true;
479             urlOptions.nowelcome = true;
480         }
481         else
482             urlOptions.pan_and_zoom = false;
483
484         // console.log(urlOptions);
485     }
486
487     netdataHashParse();
488
489     // --------------------------------------------------------------------
490     // check options that should be processed before loading netdata.js
491     
492     function loadLocalStorage(name) {
493         var ret = null;
494
495         try {
496             if(typeof Storage !== "undefined" && typeof localStorage === 'object')
497                 ret = localStorage.getItem(name);
498         }
499         catch(error) {
500             ;
501         }
502
503         if(typeof ret === 'undefined' || ret === null)
504             return null;
505
506         // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
507
508         return ret;
509     }
510
511     function saveLocalStorage(name, value) {
512         // console.log('saving: ' + name.toString() + ' = ' + value.toString());
513         try {
514             if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
515                 localStorage.setItem(name, value.toString());
516                 return true;
517             }
518         }
519         catch(error) {
520             ;
521         }
522
523         return false;
524     }
525
526     function getTheme(def) {
527         var ret = loadLocalStorage('netdataTheme');
528         if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
529             return def;
530         else
531             return ret;
532     }
533
534     function setTheme(theme) {
535         if(theme === netdataTheme) return false;
536         return saveLocalStorage('netdataTheme', theme);
537     }
538
539     var netdataTheme = getTheme('slate');
540     var netdataShowHelp = true;
541
542     if(urlOptions.theme !== null) {
543         setTheme(urlOptions.theme);
544         netdataTheme = urlOptions.theme;
545     }
546     else
547         urlOptions.theme = netdataTheme;
548
549     if(urlOptions.help !== null) {
550         saveLocalStorage('options.show_help', urlOptions.help);
551         netdataShowHelp = urlOptions.help;
552     }
553     else {
554         urlOptions.help = loadLocalStorage('options.show_help');
555     }
556
557     // --------------------------------------------------------------------
558     // registry call back to render my-netdata menu
559
560     var netdataRegistryCallback = function(machines_array) {
561         var el = '';
562         var a1 = '';
563         var found = 0;
564
565         if(machines_array === null) {
566             var ret = loadLocalStorage("registryCallback");
567             if(typeof ret !== 'undefined' && ret !== null) {
568                 machines_array = JSON.parse(ret);
569                 console.log("failed to contact the registry - loaded registry data from browser local storage");
570             }
571         }
572
573         if(machines_array) {
574             saveLocalStorage("registryCallback", JSON.stringify(machines_array));
575
576             var machines = machines_array.sort(function (a, b) {
577                 if (a.name > b.name) return -1;
578                 if (a.name < b.name) return 1;
579                 return 0;
580             });
581
582             var len = machines.length;
583             while(len--) {
584                 var u = machines[len];
585                 found++;
586                 el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
587                 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>';
588             }
589         }
590
591         if(!found) {
592             if(machines)
593                 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>';
594             else
595                 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>';
596
597             a1 += '<li><a href="#" onClick="return false;">&nbsp;</a></li>';
598
599             el += '<li role="separator" class="divider"></li>' +
600                     '<li><a href="//london.netdata.rocks/default.html">UK - London (DigitalOcean.com)</a></li>' +
601                     '<li><a href="//newyork.netdata.rocks/default.html">US - New York (DigitalOcean.com)</a></li>' +
602                     '<li><a href="//sanfrancisco.netdata.rocks/default.html">US - San Francisco (DigitalOcean.com)</a></li>' +
603                     '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
604                     '<li><a href="//frankfurt.netdata.rocks/default.html">Germany - Frankfurt (DigitalOcean.com)</a></li>' +
605                     '<li><a href="//toronto.netdata.rocks/default.html">Canada - Toronto (DigitalOcean.com)</a></li>' +
606                     '<li><a href="//singapore.netdata.rocks/default.html">Japan - Singapore (DigitalOcean.com)</a></li>' +
607                     '<li><a href="//bangalore.netdata.rocks/default.html">India - Bangalore (DigitalOcean.com)</a></li>';
608             a1 += '<li role="separator" class="divider"></li>' +
609                     '<li><a href="#">&nbsp;</a></li>' +
610                     '<li><a href="#">&nbsp;</a></li>'+
611                     '<li><a href="#">&nbsp;</a></li>'+
612                     '<li><a href="#">&nbsp;</a></li>'+
613                     '<li><a href="#">&nbsp;</a></li>'+
614                     '<li><a href="#">&nbsp;</a></li>'+
615                     '<li><a href="#">&nbsp;</a></li>'+
616                     '<li><a href="#">&nbsp;</a></li>';
617         }
618
619         el += '<li role="separator" class="divider"></li>';
620         a1 += '<li role="separator" class="divider"></li>';
621
622         el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
623         a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>'
624
625         document.getElementById('mynetdata_servers').innerHTML = el;
626         document.getElementById('mynetdata_servers2').innerHTML = el;
627         document.getElementById('mynetdata_actions1').innerHTML = a1;
628
629         gotoServerInit();
630     };
631
632     var this_is_demo = null;
633     function isdemo() {
634         if(this_is_demo !== null) return this_is_demo;
635         this_is_demo = false;
636
637         try {
638             if(typeof document.location.hostname === 'string') {
639                 if(document.location.hostname.endsWith('.my-netdata.io') ||
640                         document.location.hostname.endsWith('.mynetdata.io') ||
641                         document.location.hostname.endsWith('.netdata.rocks') ||
642                         document.location.hostname.endsWith('.firehol.org') ||
643                         document.location.hostname.endsWith('.netdata.online'))
644                         this_is_demo = true;
645             }
646         }
647         catch(error) {
648             ;
649         }
650
651         return this_is_demo;
652     }
653
654     function netdataURL(url) {
655         if(typeof url === 'undefined')
656             url = document.location.toString();
657
658         if(url.indexOf('#') !== -1)
659             url = url.substring(0, url.indexOf('#'));
660
661         var hash = netdataHash();
662
663         // console.log('netdataURL: ' + url + hash);
664
665         return url + hash;
666     }
667
668     function netdataReload(url) {
669         var t = netdataURL(url);
670         // console.log('netdataReload: ' + t);
671         document.location = t;
672
673         // since we play with hash
674         // this is needed to reload the page
675         location.reload();
676     }
677
678     var gotoServerValidateRemaining = 0;
679     var gotoServerMiddleClick = false;
680     var gotoServerStop = false;
681     function gotoServerValidateUrl(id, guid, url) {
682         var penaldy = 0;
683         var error = 'failed';
684
685         if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
686                 // we penalize https only if the current url is http
687                 // to allow the user walk through all its servers.
688                 penaldy = 500;
689
690         else if(document.location.toString().startsWith('https://') && url.toString().startsWith('http://'))
691             error = 'can\'t check';
692         
693         var finalURL = netdataURL(url);
694
695         setTimeout(function() {
696             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>';
697
698             NETDATA.registry.hello(url, function(data) {
699                 if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid === guid) {
700                     // console.log('OK ' + id + ' URL: ' + url);
701                     document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
702
703                     if(!gotoServerStop) {
704                         gotoServerStop = true;
705
706                         if(gotoServerMiddleClick) {
707                             window.open(finalURL, '_blank');
708                             gotoServerMiddleClick = false;
709                             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)';
710                         }
711                         else
712                             document.location = finalURL;
713                     }
714                 }
715                 else {
716                     if(typeof data !== 'undefined' && data !== null && typeof data.machine_guid === 'string' && data.machine_guid !== guid)
717                         error = 'wrong machine';
718
719                     document.getElementById(guid + '-' + id + '-status').innerHTML = error;
720                     gotoServerValidateRemaining--;
721                     if(gotoServerValidateRemaining <= 0) {
722                         gotoServerMiddleClick = false;
723                         document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
724                     }
725                 }
726             });
727         }, (id * 50) + penaldy);
728     }
729
730     function gotoServerModalHandler(guid) {
731         // console.log('goto server: ' + guid);
732
733         gotoServerStop = false;
734         var checked = {};
735         var len = NETDATA.registry.machines[guid].alternate_urls.length;
736         var count = 0;
737
738         document.getElementById('gotoServerResponse').innerHTML = '';
739         document.getElementById('gotoServerList').innerHTML = '';
740         document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
741         $('#gotoServerModal').modal('show');
742
743         gotoServerValidateRemaining = len;
744         while(len--) {
745             var url = NETDATA.registry.machines[guid].alternate_urls[len];
746             checked[url] = true;
747             gotoServerValidateUrl(count++, guid, url);
748         }
749
750         setTimeout(function() {
751             if(gotoServerStop === false) {
752                 document.getElementById('gotoServerResponse').innerHTML = '<b>Added all the known URLs for this machine.</b>';
753                 NETDATA.registry.search(guid, function(data) {
754                     console.log(data);
755                     len = data.urls.length;
756                     while(len--) {
757                         var url = data.urls[len][1];
758                         console.log(url);
759                         if(typeof checked[url] === 'undefined') {
760                             gotoServerValidateRemaining++;
761                             checked[url] = true;
762                             gotoServerValidateUrl(count++, guid, url);
763                         }
764                     }
765                 });
766             }
767         }, 2000);
768         return false;
769     }
770
771     function gotoServerInit() {
772         $(".registry_link").on('click', function(e) {
773             if(e.which === 2) {
774                 e.preventDefault();
775                 gotoServerMiddleClick = true;
776             }
777             else {
778                 gotoServerMiddleClick = false;
779             }
780
781             return true;
782         });
783     }
784
785     function switchRegistryModalHandler() {
786         document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
787         document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
788         document.getElementById('switchRegistryResponse').innerHTML = '';
789         $('#switchRegistryModal').modal('show');
790     }
791
792     function notifyForSwitchRegistry() {
793         var n = document.getElementById('switchRegistryPersonGUID').value;
794
795         if(n !== '' && n.length === 36) {
796             NETDATA.registry.switch(n, function(result) {
797                 if(result !== null) {
798                     $('#switchRegistryModal').modal('hide');
799                     NETDATA.registry.init();
800                 }
801                 else {
802                     document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
803                 }
804             });
805         }
806         else
807             document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
808     }
809
810     var deleteRegistryUrl = null;
811     function deleteRegistryModalHandler(guid, name, url) {
812         deleteRegistryUrl = url;
813         document.getElementById('deleteRegistryServerName').innerHTML = name;
814         document.getElementById('deleteRegistryServerName2').innerHTML = name;
815         document.getElementById('deleteRegistryServerURL').innerHTML = url;
816         document.getElementById('deleteRegistryResponse').innerHTML = '';
817         $('#deleteRegistryModal').modal('show');
818     }
819
820     function notifyForDeleteRegistry() {
821         if(deleteRegistryUrl) {
822             NETDATA.registry.delete(deleteRegistryUrl, function(result) {
823                 if(result !== null) {
824                     deleteRegistryUrl = null;
825                     $('#deleteRegistryModal').modal('hide');
826                     NETDATA.registry.init();
827                 }
828                 else {
829                     document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
830                 }
831             });
832         }
833     }
834
835     var options = {
836         sparklines_registry: {},
837         menus: {},
838         submenu_names: {},
839         data: null,
840         hostname: 'netdata_server', // will be overwritten by the netdata server
841         categories: new Array(),
842         categories_idx: {},
843         families: new Array(),
844         families_idx: {},
845
846         chartsPerRow: 0,
847         chartsMinWidth: 1450,
848         chartsHeight: 180,
849         sparklinesHeight: 60,
850     };
851
852     // generate a sparkline
853     // used in the documentation
854     function sparkline(chart, dimension, units) {
855         var key = chart + '.' + dimension;
856
857         if(typeof units === 'undefined')
858             units = '';
859
860         if(typeof options.sparklines_registry[key] === 'undefined')
861             options.sparklines_registry[key] = { count: 1 };
862         else
863             options.sparklines_registry[key].count++;
864
865         key = key + '.' + options.sparklines_registry[key].count;
866
867         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 + ')';
868
869         return h;
870     }
871
872     function chartsPerRow(total) {
873         if(options.chartsPerRow === 0) {
874             width = Math.floor(total / options.chartsMinWidth);
875             if(width === 0) width = 1;
876             return width;
877         }
878         else return options.chartsPerRow;
879     }
880
881     function prioritySort(a, b) {
882         if(a.priority < b.priority) return -1;
883         if(a.priority > b.priority) return 1;
884         if(a.name < b.name) return -1;
885         return 1;
886     }
887
888     function sortObjectByPriority(object) {
889         var idx = {};
890         var sorted = new Array();
891
892         for(var i in object) {
893             if(typeof idx[i] === 'undefined') {
894                 idx[i] = object[i];
895                 sorted.push(i);
896             }
897         }
898
899         sorted.sort(function(a, b) {
900             if(idx[a].priority < idx[b].priority) return -1;
901             if(idx[a].priority > idx[b].priority) return 1;
902             if(a < b) return -1;
903             return 1;
904         });
905
906         return sorted;
907     }
908
909
910     // ----------------------------------------------------------------------------
911     // scroll to a section, without changing the browser history
912
913     function scrollToId(hash) {
914         if(hash && hash != '') {
915             var offset = $('#' + hash).offset();
916             if(typeof offset !== 'undefined')
917                 $('html, body').animate({ scrollTop: offset.top }, 0);
918         }
919
920         // we must return false to prevent the default action
921         return false;
922     }
923
924     // ----------------------------------------------------------------------------
925
926     var netdataDashboard = {
927         menu: {},
928         submenu: {},
929         context: {},
930
931         gaugeChart: function(title, width, dimensions, colors) {
932             if(typeof colors === 'undefined')
933                 colors = '';
934
935             if(typeof dimensions === 'undefined')
936                 dimensions = '';
937
938             return '<div data-netdata="CHART_UNIQUE_ID"'
939                                     + ' data-dimensions="' + dimensions + '"'
940                                     + ' data-chart-library="gauge"'
941                                     + ' data-gauge-adjust="width"'
942                                     + ' data-title="' + title + '"'
943                                     + ' data-width="' + width + '"'
944                                     + ' data-before="0"'
945                                     + ' data-after="-CHART_DURATION"'
946                                     + ' data-points="CHART_DURATION"'
947                                     + ' data-colors="' + colors + '"'
948                                     + ' role="application"></div>';
949         },
950
951         anyAttribute: function(obj, attr, key, def) {
952             if(typeof obj[key] !== 'undefined') {
953                 if(typeof obj[key][attr] !== 'undefined')
954                     return obj[key][attr];
955             }
956             return def;
957         },
958
959         menuTitle: function(chart) {
960             if(typeof chart.menu_pattern !== 'undefined') {
961                 return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu_pattern, chart.menu_pattern).toString()
962                         + '&nbsp;' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
963             }
964
965             return (netdataDashboard.anyAttribute(netdataDashboard.menu, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
966         },
967
968         menuIcon: function(chart) {
969             if(typeof chart.menu_pattern !== 'undefined')
970                 return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
971
972             return netdataDashboard.anyAttribute(netdataDashboard.menu, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
973         },
974
975         menuInfo: function(menu) {
976             return netdataDashboard.anyAttribute(netdataDashboard.menu, 'info', menu, null);
977         },
978
979         menuHeight: function(menu, relative) {
980             return netdataDashboard.anyAttribute(netdataDashboard.menu, 'height', menu, 1.0) * relative;
981         },
982
983         submenuTitle: function(menu, submenu) {
984             var key = menu + '.' + submenu;
985             var title = netdataDashboard.anyAttribute(netdataDashboard.submenu, 'title', key, submenu).toString().replace(/_/g, ' ');;
986             if(title.length > 28) {
987                 var a = title.substring(0, 13);
988                 var b = title.substring(title.length - 12, title.length);
989                 return a + '...' + b;
990             }
991             return title;
992         },
993
994         submenuInfo: function(menu, submenu) {
995             var key = menu + '.' + submenu;
996             return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'info', key, null);
997         },
998
999         submenuHeight: function(menu, submenu, relative) {
1000             var key = menu + '.' + submenu;
1001             return netdataDashboard.anyAttribute(netdataDashboard.submenu, 'height', key, 1.0) * relative;
1002         },
1003
1004         contextInfo: function(id) {
1005             if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].info !== 'undefined')
1006                 return '<div class="chart-message netdata-chart-alignment" role="document">' + netdataDashboard.context[id].info + '</div>';
1007             else
1008                 return '';
1009         },
1010
1011         contextHeight: function(id, def) {
1012             if(typeof netdataDashboard.context[id] !== 'undefined' && typeof netdataDashboard.context[id].height !== 'undefined')
1013                 return def * netdataDashboard.context[id].height;
1014             else
1015                 return def;
1016         }
1017     };
1018
1019     // ----------------------------------------------------------------------------
1020
1021     // enrich the data structure returned by netdata
1022     // to reflect our menu system and content
1023     function enrichChartData(chart) {
1024         var tmp = chart.type.split('_')[0];
1025
1026         switch(tmp) {
1027             case 'ap':
1028             case 'net':
1029             case 'disk':
1030                 chart.menu = tmp;
1031                 break;
1032
1033             case 'cgroup':
1034                 chart.menu = chart.type;
1035                 if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
1036                     chart.menu_pattern = 'cgqemu';
1037                 else
1038                     chart.menu_pattern = 'cgroup';
1039                 break;
1040
1041             case 'apache':
1042             case 'exim':
1043             case 'memcached':
1044             case 'mysql':
1045             case 'named':
1046             case 'nginx':
1047             case 'nut':
1048             case 'phpfpm':
1049             case 'postfix':
1050             case 'redis':
1051             case 'retroshare':
1052             case 'ipfs':
1053             case 'smawebbox':
1054             case 'squid':
1055             case 'snmp':
1056             case 'tomcat':
1057                 chart.menu = chart.type;
1058                 chart.menu_pattern = tmp;
1059                 break;
1060
1061             case 'tc':
1062                 chart.menu = tmp;
1063
1064                 // find a name for this device from fireqos info
1065                 // we strip '_(in|out)' or '(in|out)_'
1066                 if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
1067                     var n = chart.name.split('.')[1];
1068                     if(n.endsWith('_in'))
1069                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
1070                     else if(n.endsWith('_out'))
1071                         options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
1072                     else if(n.startsWith('in_'))
1073                         options.submenu_names[chart.family] = n.slice(3, n.length);
1074                     else if(n.startsWith('out_'))
1075                         options.submenu_names[chart.family] = n.slice(4, n.length);
1076                 }
1077
1078                 // increase the priority of IFB devices
1079                 // to have inbound appear before outbound
1080                 if(chart.id.match(/.*-ifb$/))
1081                     chart.priority--;
1082
1083                 break;
1084
1085             default:
1086                 chart.menu = chart.type;
1087                 break;
1088         }
1089
1090         chart.submenu = chart.family;
1091     }
1092
1093     // ----------------------------------------------------------------------------
1094
1095     function headMain(charts, duration) {
1096         var head = '';
1097
1098         if(typeof charts['system.swap'] !== 'undefined')
1099             head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
1100             + ' data-dimensions="free"'
1101             + ' data-append-options="percentage"'
1102             + ' data-chart-library="easypiechart"'
1103             + ' data-title="Free Swap"'
1104             + ' data-units="%"'
1105             + ' data-easypiechart-max-value="100"'
1106             + ' data-width="8%"'
1107             + ' data-before="0"'
1108             + ' data-after="-' + duration.toString() + '"'
1109             + ' data-points="' + duration.toString() + '"'
1110             + ' data-colors="#DD4400"'
1111             + ' role="application"></div>';
1112
1113         if(typeof charts['system.io'] !== 'undefined') {
1114             head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1115             + ' data-dimensions="in"'
1116             + ' data-chart-library="easypiechart"'
1117             + ' data-title="Disk Read"'
1118             + ' data-width="10%"'
1119             + ' data-before="0"'
1120             + ' data-after="-' + duration.toString() + '"'
1121             + ' data-points="' + duration.toString() + '"'
1122             + ' role="application"></div>';
1123
1124             head += '<div style="margin-right: 10px;" data-netdata="system.io"'
1125             + ' data-dimensions="out"'
1126             + ' data-chart-library="easypiechart"'
1127             + ' data-title="Disk Write"'
1128             + ' data-width="10%"'
1129             + ' data-before="0"'
1130             + ' data-after="-' + duration.toString() + '"'
1131             + ' data-points="' + duration.toString() + '"'
1132             + ' role="application"></div>';
1133         }
1134
1135         if(typeof charts['system.cpu'] !== 'undefined')
1136             head += '<div data-netdata="system.cpu"'
1137             + ' data-chart-library="gauge"'
1138             + ' data-title="CPU"'
1139             + ' data-units="%"'
1140             + ' data-gauge-max-value="100"'
1141             + ' data-width="18%"'
1142             + ' data-after="-' + duration.toString() + '"'
1143             + ' data-points="' + duration.toString() + '"'
1144             + ' data-colors="' + NETDATA.colors[12] + '"'
1145             + ' role="application"></div>';
1146
1147         if(typeof charts['system.ipv4'] !== 'undefined') {
1148             head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1149             + ' data-dimensions="received"'
1150             + ' data-chart-library="easypiechart"'
1151             + ' data-title="IPv4 Inbound"'
1152             + ' data-width="10%"'
1153             + ' data-before="0"'
1154             + ' data-after="-' + duration.toString() + '"'
1155             + ' data-points="' + duration.toString() + '"'
1156             + ' role="application"></div>';
1157
1158             head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
1159             + ' data-dimensions="sent"'
1160             + ' data-chart-library="easypiechart"'
1161             + ' data-title="IPv4 Outbound"'
1162             + ' data-width="10%"'
1163             + ' data-before="0"'
1164             + ' data-after="-' + duration.toString() + '"'
1165             + ' data-points="' + duration.toString() + '"'
1166             + ' role="application"></div>';
1167         }
1168         else if(typeof charts['system.ipv6'] !== 'undefined') {
1169             head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1170             + ' data-dimensions="received"'
1171             + ' data-chart-library="easypiechart"'
1172             + ' data-title="IPv6 Inbound"'
1173             + ' data-units="kbps"'
1174             + ' data-width="10%"'
1175             + ' data-before="0"'
1176             + ' data-after="-' + duration.toString() + '"'
1177             + ' data-points="' + duration.toString() + '"'
1178             + ' role="application"></div>';
1179
1180             head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
1181             + ' data-dimensions="sent"'
1182             + ' data-chart-library="easypiechart"'
1183             + ' data-title="IPv6 Outbound"'
1184             + ' data-units="kbps"'
1185             + ' data-width="10%"'
1186             + ' data-before="0"'
1187             + ' data-after="-' + duration.toString() + '"'
1188             + ' data-points="' + duration.toString() + '"'
1189             + ' role="application"></div>';
1190         }
1191
1192         if(typeof charts['system.ram'] !== 'undefined')
1193             head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
1194             + ' data-dimensions="cached|free"'
1195             + ' data-append-options="percentage"'
1196             + ' data-chart-library="easypiechart"'
1197             + ' data-title="Available RAM"'
1198             + ' data-units="%"'
1199             + ' data-easypiechart-max-value="100"'
1200             + ' data-width="8%"'
1201             + ' data-after="-' + duration.toString() + '"'
1202             + ' data-points="' + duration.toString() + '"'
1203             + ' data-colors="' + NETDATA.colors[7] + '"'
1204             + ' role="application"></div>';
1205
1206         return head;
1207     }
1208
1209     function generateHeadCharts(type, chart, duration) {
1210         var head = '';
1211         var hcharts = netdataDashboard.anyAttribute(netdataDashboard.context, type, chart.context, []);
1212         if(hcharts.length > 0) {
1213             var hi = 0, hlen = hcharts.length;
1214             while(hi < hlen) {
1215                 if(typeof hcharts[hi] === 'function')
1216                     head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1217                 else
1218                     head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
1219                 hi++;
1220             }
1221         }
1222         return head;
1223     }
1224
1225     function renderPage(menus, data) {
1226         var div = document.getElementById('charts_div');
1227         var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
1228
1229         // find the proper duration for per-second updates
1230         var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
1231         var html = '';
1232         var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
1233         var mainhead = headMain(data.charts, duration);
1234
1235         // sort the menus
1236         var main = sortObjectByPriority(menus);
1237         var i = 0, len = main.length;
1238         while(i < len) {
1239             var menu = main[i++];
1240
1241             // generate an entry at the main menu
1242
1243             var menuid = NETDATA.name2id('menu_' + menu);
1244             sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
1245             html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div role="document">';
1246
1247             if(menus[menu].info !== null)
1248                 html += menus[menu].info;
1249
1250             // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
1251
1252             var shtml = '';
1253             var mhead = '<div class="netdata-chart-row">' + mainhead;
1254             mainhead = '';
1255
1256             // sort the submenus of this menu
1257             var sub = sortObjectByPriority(menus[menu].submenus);
1258             var si = 0, slen = sub.length;
1259             while(si < slen) {
1260                 var submenu = sub[si++];
1261
1262                 // generate an entry at the submenu
1263                 var submenuid = NETDATA.name2id('menu_' + menu + '_submenu_' + submenu);
1264                 sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
1265                 shtml += '<div class="netdata-group-container" id="' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
1266
1267                 if(menus[menu].submenus[submenu].info !== null)
1268                     shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
1269
1270                 var head = '<div class="netdata-chart-row">';
1271                 var chtml = '';
1272
1273                 // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
1274
1275                 // sort the charts in this submenu of this menu
1276                 menus[menu].submenus[submenu].charts.sort(prioritySort);
1277                 var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
1278                 while(ci < clen) {
1279                     var chart = menus[menu].submenus[submenu].charts[ci++];
1280
1281                     // generate the submenu heading charts
1282                     mhead += generateHeadCharts('mainheads', chart, duration);
1283                     head += generateHeadCharts('heads', chart, duration);
1284
1285                     // generate the chart
1286                     chtml += netdataDashboard.contextInfo(chart.context) + '<div id="chart_' + NETDATA.name2id(chart.id) + '" data-netdata="' + chart.id + '"'
1287                         + ' data-width="' + pcent_width.toString() + '%"'
1288                         + ' data-height="' + netdataDashboard.contextHeight(chart.context, options.chartsHeight).toString() + 'px"'
1289                         + ' data-before="0"'
1290                         + ' data-after="-' + duration.toString() + '"'
1291                         + ' data-id="' + NETDATA.name2id(options.hostname + '/' + chart.id) + '"'
1292                         + ' data-colors="' + netdataDashboard.anyAttribute(netdataDashboard.context, 'colors', chart.context, '') + '"'
1293                         + ' role="application"></div>';
1294
1295                     // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
1296                 }
1297
1298                 head += '</div>';
1299                 shtml += head + chtml + '</div>';
1300             }
1301
1302             mhead += '</div>';
1303             sidebar += '</ul></li>';
1304             html += mhead + shtml + '</div></div><hr role="separator"/>';
1305         }
1306
1307         sidebar += '</ul>';
1308         div.innerHTML = html;
1309         document.getElementById('sidebar').innerHTML = sidebar;
1310         finalizePage();
1311     }
1312
1313     function renderChartsAndMenu(data) {
1314         var menus = options.menus;
1315         var charts = data.charts;
1316
1317         for(var c in charts) {
1318             enrichChartData(charts[c]);
1319
1320             // create the menu
1321             if(typeof menus[charts[c].menu] === 'undefined') {
1322                 menus[charts[c].menu] = {
1323                     priority: charts[c].priority,
1324                     submenus: {},
1325                     title: netdataDashboard.menuTitle(charts[c]),
1326                     icon: netdataDashboard.menuIcon(charts[c]),
1327                     info: netdataDashboard.menuInfo(charts[c].menu),
1328                     height: netdataDashboard.menuHeight(charts[c].menu, options.chartsHeight)
1329                 };
1330             }
1331
1332             if(charts[c].priority < menus[charts[c].menu].priority)
1333                 menus[charts[c].menu].priority = charts[c].priority;
1334
1335             // create the submenu
1336             if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
1337                 menus[charts[c].menu].submenus[charts[c].submenu] = {
1338                     priority: charts[c].priority,
1339                     charts: new Array(),
1340                     title: null,
1341                     info: netdataDashboard.submenuInfo(charts[c].menu, charts[c].submenu),
1342                     height: netdataDashboard.submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
1343                 };
1344             }
1345
1346             if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
1347                 menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
1348
1349             // index the chart in the menu/submenu
1350             menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
1351         }
1352
1353         // propagate the descriptive subname given to QoS
1354         // to all the other submenus with the same name
1355         for(var m in menus) {
1356             for(var s in menus[m].submenus) {
1357                 // set the family using a name
1358                 if(typeof options.submenu_names[s] !== 'undefined') {
1359                     menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
1360                 }
1361                 else {
1362                     menus[m].submenus[s].title = netdataDashboard.submenuTitle(m, s);
1363                 }
1364             }
1365         }
1366
1367         renderPage(menus, data);
1368     }
1369
1370     // ----------------------------------------------------------------------------
1371
1372     function alarmsUpdateModal() {
1373         var active = '<h3>Raised Alarms</h3><table class="table">';
1374         var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
1375         var log = '<h3>Alarm Log</h3><table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th>';
1376         var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b>&nbsp;red&nbsp;</b></span> is critical, <span style="color:#fe7d37"><b>&nbsp;orange&nbsp;</b></span> is warning, <span style="color: #4c1"><b>&nbsp;bright green&nbsp;</b></span> is ok, <span style="color: #9f9f9f"><b>&nbsp;light grey&nbsp;</b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b>&nbsp;black&nbsp;</b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.<br/>netdata can send notifications for these alarms. Check <a href="https://github.com/firehol/netdata/blob/master/conf.d/health_alarm_notify.conf">this configuration file</a> for more information.';
1377
1378         NETDATA.alarms.get('all', function(data) {
1379             options.alarm_families = new Array();
1380
1381             alarmsCallback(data);
1382
1383             if(data === null) {
1384                 document.getElementById('alarms_active').innerHTML =
1385                         document.getElementById('alarms_all').innerHTML =
1386                                 document.getElementById('alarms_log').innerHTML =
1387                                         'failed to load alarm data!';
1388                 return;
1389             }
1390
1391             function frequency_text(seconds, sfx) {
1392                 if(seconds === 0)
1393                     return 'now';
1394
1395                 var suffix = '';
1396                 if(seconds < 0) {
1397                     seconds = -seconds;
1398                     if(sfx) suffix = '&nbsp;ago';
1399                 }
1400
1401                 var hours = Math.floor(seconds / 3600);
1402                 seconds -= (hours * 3600);
1403
1404                 var minutes = Math.floor(seconds / 60);
1405                 seconds -= (minutes * 60);
1406
1407                 var txt = '';
1408                 
1409                 if(hours > 1) txt += hours.toString() + '&nbsp;hours';
1410                 else if(hours === 1) txt += hours.toString() + '&nbsp;hour';
1411
1412                 if(hours > 0 && minutes > 0 && seconds == 0)
1413                     txt += '&nbsp;and&nbsp;';
1414                 else if(hours > 0 && minutes > 0 && seconds > 0)
1415                     txt += ',&nbsp;';
1416
1417                 if(minutes > 1) txt += minutes.toString() + '&nbsp;minutes';
1418                 else if(minutes === 1) txt += minutes.toString() + '&nbsp;minute';
1419
1420                 if((minutes > 0 || minutes > 0) && seconds > 0)
1421                     txt += '&nbsp;and&nbsp;';
1422
1423                 if(seconds > 1) txt += seconds.toString() + '&nbsp;seconds';
1424                 else if(seconds === 1) txt += seconds.toString() + '&nbsp;second';
1425
1426                 return txt + suffix;
1427             }
1428
1429             function alarm_lookup_explain(alarm, chart) {
1430                 var dimensions = ' of all values ';
1431
1432                 if(chart.dimensions.length > 1)
1433                     dimensions = ' of the sum of all dimensions ';
1434
1435                 if(typeof alarm.lookup_dimensions !== 'undefined') {
1436                     var d = alarm.lookup_dimensions.replace('|', ',');
1437                     var x = d.split(',');
1438                     if(x.length > 1)
1439                         dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code> ';
1440                     else
1441                         dimensions = 'of all values of dimension <code>' + alarm.lookup_dimensions + '</code> ';
1442                 }
1443
1444                 return '<code>' + alarm.lookup_method + '</code> '
1445                     + dimensions + ', of chart <code>' + alarm.chart + '</code>'
1446                     + ', starting <code>' + frequency_text(alarm.lookup_after + alarm.lookup_before, true) + '</code> and up to <code>' + frequency_text(alarm.lookup_before, true) + '</code>'
1447                     + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ',&nbsp;') + '</code>'):'')
1448                     + '.';
1449             }
1450
1451             function alarm_to_html(alarm, full) {
1452                 var chart = options.data.charts[alarm.chart];
1453
1454                 var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/>&nbsp;<br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20"/><br/>&nbsp;<br/><span style="font-size: 18px">' + alarm.info + '</span><br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b><br/>&nbsp;<br/><b><i class="fa fa-line-chart" aria-hidden="true"></i></b><small>&nbsp;&nbsp;<a href="#" onClick="NETDATA.alarms.scrollToChart(\'' + alarm.chart + '\'); $(\'#alarmsModal\').modal(\'hide\'); return false;">jump to chart</a></small></td>'
1455                     + '<td><table class="table">'
1456                     + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning&nbsp;when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
1457                     + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical&nbsp;when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
1458
1459                 if(full === true) {
1460                         html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
1461                         + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
1462                         + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
1463                         + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
1464                 }
1465
1466                 var delay = '';
1467                 if((alarm.delay_up_duration > 0 || alarm.delay_down_duration > 0) && alarm.delay_multiplier != 0 && alarm.delay_max_duration > 0) {
1468                     if(alarm.delay_up_duration == alarm.delay_down_duration) {
1469                         delay += '<small><br/>hysteresis ' + frequency_text(alarm.delay_up_duration);
1470                     }
1471                     else {
1472                         delay = '<small><br/>hysteresis ';
1473                         if(alarm.delay_up_duration > 0) {
1474                             delay += 'on&nbsp;escalation&nbsp;<code>' + frequency_text(alarm.delay_up_duration) + '</code>, ';
1475                         }
1476                         if(alarm.delay_down_duration > 0) {
1477                             delay += 'on&nbsp;recovery&nbsp;<code>' + frequency_text(alarm.delay_down_duration) + '</code>, ';
1478                         }
1479                     }
1480                     if(alarm.delay_multiplier != 1.0) {
1481                         delay += 'multiplied&nbsp;by&nbsp;<code>' + alarm.delay_multiplier.toString() + '</code>';
1482                         delay += ',&nbsp;up&nbsp;to&nbsp;<code>' + frequency_text(alarm.delay_max_duration) + '</code>';
1483                     }
1484                     delay += '</small>';
1485                 }
1486
1487                 html += '<tr><td width="10%" style="text-align:right">check&nbsp;every</td><td>' + frequency_text(alarm.update_every) + '</td></tr>'
1488                     + '<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span>' + delay + '</td></tr>'
1489                     + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
1490                     + '</table></td></tr>';
1491
1492                 return html;
1493             }
1494
1495             function alarm_family_show(id) {
1496                 var html = '<table class="table">';
1497                 var family = options.alarm_families[id];
1498                 var len = family.arr.length;
1499                 while(len--) {
1500                     var alarm = family.arr[len];
1501                     html += alarm_to_html(alarm, true);
1502                 }
1503                 html += '</table>';
1504
1505                 $('#alarm_all_' + id.toString()).html(html);
1506             }
1507
1508             // find the proper family of each alarm
1509             var now = new Date().getTime();
1510             var x;
1511             var count_active = 0;
1512             var count_all = 0;
1513             var families = {};
1514             var families_sort = new Array();
1515             for(x in data.alarms) {
1516                 var alarm = data.alarms[x];
1517                 var family = alarm.family;
1518
1519                 // find the chart
1520                 var chart = options.data.charts[alarm.chart];
1521                 if(typeof chart === 'undefined')
1522                     chart = options.data.charts_by_name[alarm.chart];
1523
1524                 // not found - this should never happen!
1525                 if(typeof chart === 'undefined') {
1526                     console.log('WARNING: alarm ' + x + ' is linked to chart ' + alarm.chart + ', which is not found in the list of chart got from the server.');
1527                     chart = { priority: 9999999 };
1528                 }
1529                 else if(typeof chart.menu !== 'undefined' && typeof chart.submenu !== 'undefined')
1530                     // the family based on the chart
1531                     family = chart.menu + ' - ' + chart.submenu;
1532
1533                 if(typeof families[family] === 'undefined') {
1534                     families[family] = {
1535                         name: family,
1536                         arr: new Array(),
1537                         priority: chart.priority
1538                     };
1539
1540                     families_sort.push(families[family]);
1541                 }
1542
1543                 if(chart.priority < families[family].priority)
1544                     families[family].priority = chart.priority;
1545
1546                 families[family].arr.unshift(alarm);
1547             }
1548
1549             // sort the families, like the dashboard menu does
1550             var families_sorted = families_sort.sort(function (a, b) {
1551                 if (a.priority > b.priority) return -1;
1552                 if (a.priority < b.priority) return 1;
1553                 return 0;
1554             });
1555
1556             var fc = 0;
1557             var len = families_sorted.length;
1558             while(len--) {
1559                 var family = families_sorted[len].name;
1560                 var active_family_added = false;
1561                 var expanded = 'true';
1562                 var collapsed = '';
1563                 var cin = 'in';
1564
1565                 if(fc !== 0) {
1566                     all += "</table></div></div></div>";
1567                     expanded = 'false';
1568                     collapsed = 'class="collapsed"'
1569                     cin = '';
1570                 }
1571
1572                 all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
1573
1574                 options.alarm_families[fc] = families[family];
1575
1576                 fc++;
1577
1578                 var arr = families[family].arr;
1579                 var c = arr.length;
1580                 while(c--) {
1581                     var alarm = arr[c];
1582                     if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
1583                         if(!active_family_added) {
1584                             active_family_added = true;
1585                             active += '<tr><th class="text-center" colspan="2"><h4>' + family + '</h4></th></tr>';
1586                         }
1587                         count_active++;
1588                         active += alarm_to_html(alarm, true);
1589                     }
1590
1591                     count_all++;
1592                 }
1593             }
1594             active += "</table>";
1595             if(families_sorted.length > 0) all += "</div></div></div>";
1596             all += "</div>";
1597
1598             if(!count_active)
1599                 active += "<h4>Everything is normal. No raised alarms.</h4>";
1600             else
1601                 active += footer;
1602
1603             if(!count_all)
1604                 all += "<h4>No alarms are running in this system.</h4>";
1605             else
1606                 all += footer;
1607
1608             document.getElementById('alarms_active').innerHTML = active;
1609             document.getElementById('alarms_all').innerHTML = all;
1610
1611             if(families_sorted.length > 0) alarm_family_show(0);
1612
1613             // register bootstrap events
1614             $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
1615                 var target = $(d.target);
1616                 var id = $(target).data('alarm-id');
1617                 alarm_family_show(id);
1618             });
1619             $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
1620                 var target = $(d.target);
1621                 var id = $(target).data('alarm-id');
1622                 $('#alarm_all_' + id.toString()).html('');
1623             });
1624
1625             NETDATA.alarms.get_log(0, function(data) {
1626                 if(data === null) {
1627                     document.getElementById('alarms_log').innerHTML =
1628                             'failed to load alarm data!';
1629                     return;
1630                 }
1631
1632                 var i = 0;
1633                 var len = data.length;
1634                 if(len > 50) len = 50;
1635                 while(i < len) {
1636                     var time = new Date(data[i].when * 1000);
1637                     log += '<tr><td>'
1638                             + time.toLocaleDateString() + ' '
1639                             + time.toLocaleTimeString() + '</td><td>'
1640                             + data[i].chart.toString() + '</td><td>'
1641                             + data[i].name.toString() + ' = ' + ((data[i].value !== null)?Math.floor(data[i].value):'NaN').toString() + ' ' + data[i].units.toString() + '</td><td>'
1642                             + data[i].status.toString() + '</td></tr>';
1643                     i++;
1644                 }
1645                 log += "</table>";
1646
1647                 if(i == 0)
1648                     log += "<h4>No alarms have been logged in this system.</h4>";
1649
1650                 document.getElementById('alarms_log').innerHTML = log;
1651             })
1652         });
1653     }
1654
1655     function alarmsCallback(data) {
1656         var count = 0;
1657         for(x in data.alarms) {
1658             var alarm = data.alarms[x];
1659             if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
1660                 count++;
1661         }
1662
1663         if(count > 0)
1664             document.getElementById('alarms_count_badge').innerHTML = count.toString();
1665         else
1666             document.getElementById('alarms_count_badge').innerHTML = '';
1667     }
1668
1669     function initializeDynamicDashboard(netdata_url) {
1670         if(typeof netdata_url === 'undefined' || netdata_url === null)
1671             netdata_url = NETDATA.serverDefault;
1672
1673         // initialize clickable alarms
1674         NETDATA.alarms.chart_div_offset = 100;
1675         NETDATA.alarms.chart_div_id_prefix = 'chart_';
1676         NETDATA.alarms.chart_div_animation_duration = 0;
1677
1678         NETDATA.pause(function() {
1679             NETDATA.alarms.callback = alarmsCallback;
1680
1681             // download all the charts the server knows
1682             NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
1683                 if(data !== null) {
1684                     options.hostname = data.hostname;
1685                     options.data = data;
1686
1687                     // update the dashboard hostname
1688                     document.getElementById('hostname').innerHTML = options.hostname;
1689                     document.getElementById('hostname').href = NETDATA.serverDefault;
1690
1691                     // update the dashboard title
1692                     document.title = options.hostname + ' netdata dashboard';
1693
1694                     // close the splash screen
1695                     $("#loadOverlay").css("display","none");
1696
1697                     // create a chart_by_name index
1698                     data.charts_by_name = {};
1699                     var charts = data.charts;
1700                     var x;
1701                     for(x in charts) {
1702                         var chart = charts[x];
1703                         data.charts_by_name[chart.name] = chart;
1704                     }
1705
1706                     // render all charts
1707                     renderChartsAndMenu(data);
1708                 }
1709             });
1710         });
1711     }
1712
1713     // ----------------------------------------------------------------------------
1714
1715     function versionLog(msg) {
1716         document.getElementById('versionCheckLog').innerHTML = msg;
1717     }
1718
1719     function getNetdataVersion(callback) {
1720         versionLog('Downloading installed version info from netdata...');
1721
1722         $.ajax({
1723             url: 'version.txt',
1724             async: true,
1725             cache: false
1726         })
1727         .done(function(data) {
1728             data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
1729             if(data.length !== 40) {
1730                 versionLog('Received version string is invalid.');
1731                 callback(null);
1732             }
1733             else {
1734                 versionLog('Installed version of netdata is ' + data);
1735                 document.getElementById('netdataVersion').innerHTML = data;
1736                 callback(data);
1737             }
1738         })
1739         .fail(function() {
1740             versionLog('Failed to download installed version info from netdata!');
1741             callback(null);
1742         });
1743     }
1744
1745     function getGithubLatestCommit(callback) {
1746         versionLog('Downloading latest version info from github...');
1747
1748         $.ajax({
1749             url: 'https://api.github.com/repos/firehol/netdata/commits',
1750             async: true,
1751             cache: false
1752         })
1753         .done(function(data) {
1754             versionLog('Latest version info from github is ' + data[0].sha);
1755             callback(data[0].sha);
1756         })
1757         .fail(function() {
1758             versionLog('Failed to download installed version info from github!');
1759             callback(null);
1760         });
1761     }
1762
1763     function checkForUpdate(callback) {
1764         getNetdataVersion(function(sha1) {
1765             if(sha1 === null) callback(null, null);
1766
1767             getGithubLatestCommit(function(sha2) {
1768                 callback(sha1, sha2);
1769             });
1770         });
1771
1772         return null;
1773     }
1774
1775     function notifyForUpdate(force) {
1776         versionLog('<p>checking for updates...</p>');
1777
1778         var now = new Date().getTime();
1779
1780         if(typeof force === 'undefined' || force !== true) {
1781             var last = loadLocalStorage('last_update_check');
1782
1783             if(typeof last === 'string')
1784                 last = parseInt(last);
1785             else
1786                 last = 0;
1787
1788             if(now - last < 3600000 * 8) {
1789                 // no need to check it - too soon
1790                 return;
1791             }
1792         }
1793
1794         checkForUpdate(function(sha1, sha2) {
1795             var save = false;
1796
1797             if(sha1 === null) {
1798                 save = false;
1799                 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>');
1800             }
1801             else if(sha2 === null) {
1802                 save = false;
1803                 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>');
1804             }
1805             else if(sha1 === sha2) {
1806                 save = true;
1807                 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>');
1808             }
1809             else {
1810                 save = true;
1811                 var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
1812
1813                 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>');
1814
1815                 document.getElementById('update_badge').innerHTML = '!';
1816             }
1817
1818             if(save)
1819                 saveLocalStorage('last_update_check', now.toString());
1820         });
1821     }
1822
1823     // ----------------------------------------------------------------------------
1824
1825     function finalizePage() {
1826         // resize all charts - without starting the background thread
1827         // this has to be done while NETDATA is paused
1828         // if we ommit this, the affix menu will be wrong, since all
1829         // the Dom elements are initially zero-sized
1830         NETDATA.parseDom();
1831
1832         if(urlOptions.pan_and_zoom === true)
1833             NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
1834
1835         // ------------------------------------------------------------------------
1836         // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
1837         $.fn.shorten = function(settings) {
1838             "use strict";
1839
1840             var config = {
1841                 showChars: 750,
1842                 minHideChars: 10,
1843                 ellipsesText: "...",
1844                 moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
1845                 lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
1846                 onLess: function() { NETDATA.onscroll(); },
1847                 onMore: function() { NETDATA.onscroll(); },
1848                 errMsg: null,
1849                 force: false
1850             };
1851
1852             if (settings) {
1853                 $.extend(config, settings);
1854             }
1855
1856             if ($(this).data('jquery.shorten') && !config.force) {
1857                 return false;
1858             }
1859             $(this).data('jquery.shorten', true);
1860
1861             $(document).off("click", '.morelink');
1862
1863             $(document).on({
1864                 click: function() {
1865
1866                     var $this = $(this);
1867                     if ($this.hasClass('less')) {
1868                         $this.removeClass('less');
1869                         $this.html(config.moreText);
1870                         $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
1871                             config.onLess();
1872                         });
1873
1874                     } else {
1875                         $this.addClass('less');
1876                         $this.html(config.lessText);
1877                         $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
1878                             config.onMore();
1879                         });
1880                     }
1881                     return false;
1882                 }
1883             }, '.morelink');
1884
1885             return this.each(function() {
1886                 var $this = $(this);
1887
1888                 var content = $this.html();
1889                 var contentlen = $this.text().length;
1890                 if (contentlen > config.showChars + config.minHideChars) {
1891                     var c = content.substr(0, config.showChars);
1892                     if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
1893                     {
1894                         var inTag = false; // I'm in a tag?
1895                         var bag = ''; // Put the characters to be shown here
1896                         var countChars = 0; // Current bag size
1897                         var openTags = []; // Stack for opened tags, so I can close them later
1898                         var tagName = null;
1899
1900                         for (var i = 0, r = 0; r <= config.showChars; i++) {
1901                             if (content[i] == '<' && !inTag) {
1902                                 inTag = true;
1903
1904                                 // This could be "tag" or "/tag"
1905                                 tagName = content.substring(i + 1, content.indexOf('>', i));
1906
1907                                 // If its a closing tag
1908                                 if (tagName[0] == '/') {
1909
1910
1911                                     if (tagName != '/' + openTags[0]) {
1912                                         config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
1913                                     } else {
1914                                         openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
1915                                     }
1916
1917                                 } else {
1918                                     // There are some nasty tags that don't have a close tag like <br/>
1919                                     if (tagName.toLowerCase() != 'br') {
1920                                         openTags.unshift(tagName); // Add to start the name of the tag that opens
1921                                     }
1922                                 }
1923                             }
1924                             if (inTag && content[i] == '>') {
1925                                 inTag = false;
1926                             }
1927
1928                             if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
1929                             else {
1930                                 r++;
1931                                 if (countChars <= config.showChars) {
1932                                     bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
1933                                     countChars++;
1934                                 } else // Now I have the characters needed
1935                                 {
1936                                     if (openTags.length > 0) // I have unclosed tags
1937                                     {
1938                                         //console.log('They were open tags');
1939                                         //console.log(openTags);
1940                                         for (j = 0; j < openTags.length; j++) {
1941                                             //console.log('Cierro tag ' + openTags[j]);
1942                                             bag += '</' + openTags[j] + '>'; // Close all tags that were opened
1943
1944                                             // 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
1945                                         }
1946                                         break;
1947                                     }
1948                                 }
1949                             }
1950                         }
1951                         c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
1952                     }else{
1953                         c+=config.ellipsesText;
1954                     }
1955
1956                     var html = '<div class="shortcontent">' + c +
1957                             '</div><div class="allcontent">' + content +
1958                             '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
1959
1960                     $this.html(html);
1961                     $this.find(".allcontent").hide(); // Hide all text
1962                     $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
1963                 }
1964             });
1965
1966         };
1967         $(".chart-message").shorten();
1968         // ------------------------------------------------------------------------
1969
1970         // callback for us to track PanAndZoom operations
1971         NETDATA.globalPanAndZoom.callback = netdataPanAndZoomCallback;
1972
1973         // let it run (update the charts)
1974         NETDATA.unpause();
1975
1976         // check if we have to jump to a specific section
1977         scrollToId(urlOptions.hash.replace('#',''));
1978
1979         if(urlOptions.chart !== null) {
1980             NETDATA.alarms.scrollToChart(urlOptions.chart);
1981             //urlOptions.hash = '#' + NETDATA.name2id('menu_' + charts[c].menu + '_submenu_' + charts[c].submenu);
1982             //urlOptions.hash = '#chart_' + NETDATA.name2id(urlOptions.chart);
1983             //console.log('hash = ' + urlOptions.hash);
1984         }
1985
1986         /* activate bootstrap sidebar (affix) */
1987         $('#sidebar').affix({
1988             offset: {
1989                 top: (isdemo())?150:0,
1990                 bottom: 0
1991             }
1992         });
1993
1994         /* fix scrolling of very long affix lists
1995            http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
1996          */
1997         $('#sidebar').on('affixed.bs.affix', function() {
1998             $(this).removeAttr('style');
1999         });
2000
2001         /* activate bootstrap scrollspy (needed for sidebar) */
2002         $(document.body).scrollspy({
2003             target: '#sidebar',
2004             offset: $(window).height() / 5 // controls the diff of the <hX> element to the top, to select it
2005         });
2006
2007         // change the URL based on the current position of the screen
2008         $('#sidebar').on('activate.bs.scrollspy', function (e) {
2009             // console.log(e);
2010             var el = $(e.target);
2011             //if(el.find('ul').size() == 0) {
2012             var hash = el.find('a').attr('href');
2013             if(typeof hash === 'string' && hash.substring(0, 1) === '#' && urlOptions.hash.startsWith(hash + '_submenu_') === false) {
2014                 urlOptions.hash = hash;
2015                 //console.log(urlOptions.hash);
2016                 netdataHashUpdate();
2017             }
2018             //else console.log('hash: not accepting ' + hash);
2019             //}
2020             //else console.log('el.find(): not found');
2021         });
2022
2023         document.getElementById('footer').style.display = 'block';
2024
2025         var update_options_modal = function() {
2026             // console.log('update_options_modal');
2027
2028             var sync_option = function(option) {
2029                 var self = $('#' + option);
2030
2031                 if(self.prop('checked') !== NETDATA.getOption(option)) {
2032                     // console.log('switching ' + option.toString());
2033                     self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
2034                 }
2035             }
2036
2037             var theme_sync_option = function(option) {
2038                 var self = $('#' + option);
2039
2040                 self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
2041             }
2042
2043             sync_option('eliminate_zero_dimensions');
2044             sync_option('destroy_on_hide');
2045             sync_option('parallel_refresher');
2046             sync_option('concurrent_refreshes');
2047             sync_option('sync_selection');
2048             sync_option('sync_pan_and_zoom');
2049             sync_option('stop_updates_when_focus_is_lost');
2050             sync_option('smooth_plot');
2051             sync_option('pan_and_zoom_data_padding');
2052             sync_option('show_help');
2053             theme_sync_option('netdata_theme_control');
2054
2055             if(NETDATA.getOption('parallel_refresher') === false) {
2056                 $('#concurrent_refreshes_row').hide();
2057             }
2058             else {
2059                 $('#concurrent_refreshes_row').show();
2060             }
2061         };
2062         NETDATA.setOption('setOptionCallback', update_options_modal);
2063
2064         // handle options changes
2065         $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
2066         $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
2067         $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
2068         $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
2069         $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
2070         $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
2071         $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
2072         $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
2073         $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
2074         $('#show_help').change(function()                       {
2075             urlOptions.help = $(this).prop('checked');
2076             NETDATA.setOption('show_help', urlOptions.help);
2077             netdataReload();
2078         });
2079
2080         // this has to be the last
2081         // it reloads the page
2082         $('#netdata_theme_control').change(function() {
2083             urlOptions.theme = $(this).prop('checked')?'slate':'white';
2084             if(setTheme(urlOptions.theme))
2085                 netdataReload();
2086         });
2087
2088         $('#updateModal').on('shown.bs.modal', function() {
2089             notifyForUpdate(true);
2090         });
2091
2092         $('#alarmsModal').on('shown.bs.modal', function() {
2093             NETDATA.pause(alarmsUpdateModal);
2094         });
2095
2096         $('#alarmsModal').on('hidden.bs.modal', function() {
2097             NETDATA.unpause();
2098             document.getElementById('alarms_active').innerHTML =
2099                     document.getElementById('alarms_all').innerHTML =
2100                     document.getElementById('alarms_log').innerHTML =
2101                             'loading...';
2102         });
2103
2104         $('#deleteRegistryModal').on('hidden.bs.modal', function() {
2105             deleteRegistryGuid = null;
2106         });
2107
2108         if(isdemo()) {
2109             if(urlOptions.nowelcome !== true) {
2110                 setTimeout(function() {
2111                     $('#welcomeModal').modal();
2112                 }, 1000);
2113             }
2114
2115             // google analytics when this is used for the home page of the demo sites
2116             // this does not run on user's installations
2117             setTimeout(function() {
2118                 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
2119                 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
2120                 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
2121                 })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
2122
2123                 ga('create', 'UA-64295674-3', 'auto');
2124                 ga('send', 'pageview');
2125             }, 2000);
2126         }
2127         else notifyForUpdate();
2128
2129         if(urlOptions.show_alarms === true)
2130             setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000);
2131     }
2132
2133     function resetDashboardOptions() {
2134         var help = NETDATA.options.current.show_help;
2135
2136         NETDATA.resetOptions();
2137         if(setTheme('slate'))
2138             netdataReload();
2139
2140         if(help !== NETDATA.options.current.show_help)
2141             netdataReload();
2142     }
2143
2144     // callback to add the dashboard info to the
2145     // parallel javascript downloader in netdata
2146     var netdataPrepCallback = function() {
2147         NETDATA.requiredJs.push({
2148             url: NETDATA.serverDefault + 'dashboard_info.js?v57',
2149             isAlreadyLoaded: function() { return false; }
2150         });
2151         
2152         if(isdemo()) {
2153             document.getElementById('masthead').style.display = 'block';
2154         }
2155     }
2156
2157     // our entry point
2158     var netdataCallback = initializeDynamicDashboard;
2159
2160 </script>
2161
2162 <body data-spy="scroll" data-target="#sidebar">
2163     <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
2164         netdata<br/><div style="font-size: 3vh;">Real-time performance monitoring, done right!</div>
2165     </div>
2166     <script type="text/javascript">
2167         // change the loadOverlay colors ASAP to match the theme
2168         document.getElementById('loadOverlay').style = (urlOptions.theme === 'slate')?"background-color:#272b30; color: #373b40;":"background-color:#fff; color: #ddd;";
2169     </script>
2170     <nav class="navbar navbar-default navbar-fixed-top" role="banner">
2171         <div class="container">
2172             <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
2173                 <ul class="nav navbar-nav">
2174                     <li class="dropdown">
2175                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
2176                         <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
2177                             <div class="row">
2178                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
2179                                     <ul id="mynetdata_servers" class="multi-column-dropdown">
2180                                         <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
2181                                     </ul>
2182                                 </div>
2183                                 <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
2184                                     <ul id="mynetdata_actions1" class="multi-column-dropdown">
2185                                     <li style="color: #999;">&nbsp;</li>
2186                                     </ul>
2187                                 </div>
2188                             </div>
2189                         </ul>
2190                     </li>
2191                 </ul>
2192             </nav>
2193             <div class="navbar-header">
2194                 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
2195                     <span class="sr-only">Toggle navigation</span>
2196                     <span class="icon-bar"></span>
2197                     <span class="icon-bar"></span>
2198                     <span class="icon-bar"></span>
2199                 </button>
2200                 <a href="/" class="navbar-brand" id="hostname" title="reload the dashboard">netdata</a>
2201             </div>
2202             <nav class="collapse navbar-collapse navbar-right" role="navigation">
2203                 <ul class="nav navbar-nav">
2204                     <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i></span>&nbsp;<span class="hidden-sm">Alarms&nbsp;</span><span id="alarms_count_badge" class="badge"></a></li>
2205                     <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i>&nbsp;<span class="hidden-sm">Settings</span></a></li>
2206                     <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata community"><i class="fa fa-github"></i>&nbsp;<span class="hidden-sm hidden-md">Community</span></a></li>
2207                     <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i><span id="update_badge" class="badge"></span>&nbsp;<span class="hidden-sm hidden-md">Update</span></a></li>
2208                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i>&nbsp;<span class="hidden-sm hidden-md">Help</span></a></li>
2209                     <!--
2210                     <li class="dropdown hidden-md hidden-lg hidden-xs">
2211                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
2212                         <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
2213                             <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fa fa-bell"></i> alarms</a></li>
2214                             <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-sliders"></i> settings</a></li>
2215                             <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
2216                             <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
2217                         </ul>
2218                     </li>
2219                     -->
2220                     <li class="dropdown hidden-sm hidden-md hidden-lg">
2221                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
2222                         <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
2223                             <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
2224                         </ul>
2225                     </li>
2226                 </ul>
2227             </nav>
2228     </nav>
2229         </div>
2230     </nav>
2231
2232     <div id="masthead" style="display: none;">
2233         <div class="container">
2234             <div class="row">
2235                 <div class="col-md-7">
2236                     <h1>Netdata
2237                         <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
2238                     </h1>
2239                 </div>
2240                 <div class="col-md-5">
2241                     <div class="well well-lg">
2242                         <div class="row">
2243                         <div class="col-md-6">
2244                             <b>Drag</b> charts to pan.
2245                             <b>Shift + wheel</b> on them, to zoom in and out.
2246                             <b>Double-click</b> on them, to reset.
2247                             <b>Hover</b> on them too!
2248                             </div>
2249                         <div class="col-md-6">
2250                             <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>
2251                             </div>
2252                         </div>
2253                     </div>
2254                 </div>
2255             </div>
2256         </div>
2257     </div>
2258
2259     <div class="container">
2260         <div class="row">
2261             <div class="charts-body" role="main">
2262                 <div id="charts_div"></div>
2263             </div>
2264             <div class="sidebar-body hidden-xs hidden-sm" role="complementary">
2265                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
2266             </div>
2267         </div>
2268     </div>
2269
2270     <div id="footer" class="container" style="display: none;">
2271         <div class="row">
2272             <div class="col-md-10" role="main">
2273                 <div class="p">
2274                     <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
2275                     <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
2276                     Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
2277                 </div>
2278                 <div class="p">
2279                     <small>
2280                         <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
2281
2282                         <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
2283                         <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
2284
2285                         <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
2286                         <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>
2287
2288                         <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
2289                         <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>
2290
2291                         <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
2292                         <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>
2293
2294                         <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
2295                         <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
2296
2297                         <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
2298                         <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
2299
2300                         <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
2301                         <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
2302
2303                         <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
2304                         <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>
2305
2306                         <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
2307                         <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>
2308
2309                         <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
2310                         <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>
2311
2312                         <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
2313                         <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>
2314
2315                         <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.
2316
2317                         <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
2318                         <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
2319
2320                         <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
2321                         <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
2322
2323                         <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
2324                         <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>
2325
2326                         <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
2327                         <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
2328
2329                     </small>
2330                 </div>
2331             </div>
2332         </div>
2333     </div>
2334
2335     <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
2336         <div class="modal-dialog modal-lg" role="document">
2337             <div class="modal-content">
2338                 <div class="modal-header">
2339                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2340                     <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
2341                 </div>
2342                 <div class="modal-body">
2343                         <div class="p">
2344                         <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.
2345                         </div>
2346                         <div class="p">
2347                         <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.
2348                         </div>
2349                         <div class="p">
2350                         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.
2351                         </div>
2352                         <div class="p">
2353                         <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>%),
2354                         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).
2355                         </div>
2356                         <div class="p">
2357                         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>!).
2358                         </div>
2359                         <div class="p">
2360                         For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
2361                         </div>
2362                 </div>
2363                 <div class="modal-footer">
2364                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2365                 </div>
2366             </div>
2367         </div>
2368     </div>
2369
2370     <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
2371         <div class="modal-dialog modal-lg" role="document">
2372             <div class="modal-content">
2373                 <div class="modal-header">
2374                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2375                     <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
2376                 </div>
2377                 <div class="modal-body">
2378
2379                     <h4>Dygraphs (line, area and stacked area charts)</h4>
2380
2381                     <!-- Nav tabs -->
2382                     <ul class="nav nav-tabs" role="tablist">
2383                         <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
2384                         <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
2385                     </ul>
2386
2387                     <!-- Tab panes -->
2388                     <div class="tab-content">
2389                         <div role="tabpanel" class="tab-pane active" id="help_mouse">
2390                             <div class="p">
2391                                 <h4>Mouse Over / Hover</h4>
2392                                 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).
2393                                 <br/>
2394                                 All the other visible charts will also show and highlight their values for the same timestamp.
2395                             </div>
2396                             <hr/>
2397                             <div class="p">
2398                                 <h4>Drag Chart Contents</h4>
2399                                 Drag the contents of a chart to pan it horizontally.
2400                                 <br/>
2401                                 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).
2402                                 <br/>
2403                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
2404                             </div>
2405                             <hr/>
2406                             <div class="p">
2407                                 <h4>Double Click</h4>
2408                                 Double Click a chart to reset all the charts to their default auto-refreshing state.
2409                             </div>
2410                             <hr/>
2411                             <div class="p">
2412                                 <h4>SHIFT + Drag</h4>
2413                                 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:
2414                                 <ul>
2415                                     <li>The already loaded chart contents are zoomed (low resolution)</li>
2416                                     <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
2417                                 </ul>
2418                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
2419                             </div>
2420                             <hr/>
2421                             <div class="p">
2422                                 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
2423                                 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.
2424                                 <br/>
2425                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
2426                             </div>
2427                             <hr/>
2428                             <div class="p">
2429                                 <h4>Legend Operations</h4>
2430                                 Click on the label or value of a dimension, will select / un-select this dimension.
2431                                 <br/>
2432                                 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
2433                             </div>
2434                         </div>
2435                         <div role="tabpanel" class="tab-pane" id="help_touch">
2436                             <div class="p">
2437                                 <h4>Single Tap</h4>
2438                                 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).
2439                                 <br/>
2440                                 All the other visible charts will also show and highlight their values for the same timestamp.
2441                             </div>
2442                             <hr/>
2443                             <div class="p">
2444                                 <h4>Drag Chart Contents</h4>
2445                                 Touch and Drag the contents of a chart to pan it horizontally.
2446                                 <br/>
2447                                 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).
2448                                 <br/>
2449                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
2450                             </div>
2451                             <hr/>
2452                             <div class="p">
2453                                 <h4>Double Tap</h4>
2454                                 Double tap a chart to reset all the charts to their default auto-refreshing state.
2455                             </div>
2456                             <hr/>
2457                             <div class="p">
2458                                 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
2459                                 With two fingers, zoom in or out.
2460                                 <br/>
2461                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
2462                             </div>
2463                             <hr/>
2464                             <div class="p">
2465                                 <h4>Legend Operations</h4>
2466                                 Tap on the label or value of a dimension, will select / un-select this dimension.
2467                             </div>
2468                         </div>
2469                     </div>
2470                 </div>
2471                 <div class="modal-footer">
2472                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2473                 </div>
2474             </div>
2475         </div>
2476     </div>
2477
2478     <div class="modal fade" id="alarmsModal" tabindex="-1" role="dialog" aria-labelledby="alarmsModalLabel">
2479         <div class="modal-dialog modal-lg" role="document">
2480             <div class="modal-content">
2481                 <div class="modal-header">
2482                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2483                     <h4 class="modal-title" id="alarmsModalLabel">netdata alarms</h4>
2484                 </div>
2485                 <div class="modal-body">
2486                     <!-- Nav tabs -->
2487                     <ul class="nav nav-tabs" role="tablist">
2488                         <li role="presentation" class="active"><a href="#alarms_active" aria-controls="alarms_active" role="tab" data-toggle="tab">Active</a></li>
2489                         <li role="presentation"><a href="#alarms_all" aria-controls="alarms_all" role="tab" data-toggle="tab">All</a></li>
2490                         <li role="presentation"><a href="#alarms_log" aria-controls="alarms_log" role="tab" data-toggle="tab">Log</a></li>
2491                     </ul>
2492
2493                     <!-- Tab panes -->
2494                     <div class="tab-content">
2495                         <div role="tabpanel" class="tab-pane active" id="alarms_active">
2496                             loading...
2497                         </div>
2498                         <div role="tabpanel" class="tab-pane" id="alarms_all">
2499                             loading...
2500                         </div>
2501                         <div role="tabpanel" class="tab-pane" id="alarms_log">
2502                             loading...
2503                         </div>
2504                     </div>
2505                 </div>
2506                 <div class="modal-footer">
2507                     <!-- <a href="#" onclick="alarmsUpdateModal(); return false;" type="button" class="btn btn-default">Update</a> -->
2508                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2509                 </div>
2510             </div>
2511         </div>
2512     </div>
2513
2514     <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
2515         <div class="modal-dialog modal-lg" role="document">
2516             <div class="modal-content">
2517                 <div class="modal-header">
2518                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2519                     <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
2520                 </div>
2521                 <div class="modal-body">
2522                     <center>
2523                         <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
2524                         <br/>
2525                         Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
2526                         <br/>
2527                         To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
2528                     </center>
2529                     <div style="padding: 10px;"></div>
2530
2531                     <!-- Nav tabs -->
2532                     <ul class="nav nav-tabs" role="tablist">
2533                         <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
2534                         <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
2535                         <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
2536                     </ul>
2537
2538                     <!-- Tab panes -->
2539                     <div class="tab-content">
2540                         <div role="tabpanel" class="tab-pane active" id="settings_performance">
2541                             <form id="optionsForm1" method="get" class="form-horizontal">
2542                                 <div class="form-group">
2543                                     <table>
2544                                     <tr class="option-row">
2545                                         <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>
2546                                         <td class="option-info"><strong>When to refresh the charts?</strong><br/>
2547                                             <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>
2548                                         </td>
2549                                         </tr>
2550                                     <tr class="option-row">
2551                                         <td class="option-control">
2552                                         <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
2553                                         </td>
2554                                         <td class="option-info"><strong>Which dimensions to show?</strong><br/>
2555                                             <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>
2556                                         </td>
2557                                         </tr>
2558                                     <tr class="option-row">
2559                                         <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
2560                                         <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
2561                                             <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>
2562                                         </td>
2563                                         </tr>
2564                                     </table>
2565                                 </div>
2566                             </form>
2567                         </div>
2568                         <div role="tabpanel" class="tab-pane" id="settings_sync">
2569                             <form id="optionsForm2" method="get" class="form-horizontal">
2570                                 <div class="form-group">
2571                                     <table>
2572                                     <tr class="option-row">
2573                                         <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
2574                                         <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
2575                                             <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>
2576                                         </td>
2577                                         </tr>
2578                                     <tr class="option-row" id="concurrent_refreshes_row">
2579                                         <td class="option-control"></td>
2580                                         <td class="option-info">
2581                                             <table>
2582                                             <tr class="option-row">
2583                                             <td class="option-control">
2584                                             <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
2585                                             </td>
2586                                             <td class="option-info">
2587                                             <strong>Shall we re-sync chart refreshes?</strong><br/>
2588                                             <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>
2589                                             </td>
2590                                             </tr>
2591                                             </table>
2592                                         </td>
2593                                         </tr>
2594                                     <tr class="option-row">
2595                                         <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>
2596                                         <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
2597                                             <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>
2598                                         </td>
2599                                         </tr>
2600                                     <tr class="option-row">
2601                                         <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>
2602                                         <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
2603                                             <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>
2604                                         </td>
2605                                         </tr>
2606                                     </table>
2607                                 </div>
2608                             </form>
2609                         </div>
2610                         <div role="tabpanel" class="tab-pane" id="settings_visual">
2611                             <form id="optionsForm3" method="get" class="form-horizontal">
2612                                 <div class="form-group">
2613                                     <table>
2614                                     <tr class="option-row">
2615                                         <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>
2616                                         <td class="option-info"><strong>Which theme to use?</strong><br/>
2617                                             <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
2618                                             <br/>
2619                                             <b>Switching this will reload the dashboard</b>.
2620                                             </small>
2621                                         </td>
2622                                         </tr>
2623                                     <tr class="option-row">
2624                                         <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>
2625                                         <td class="option-info"><strong>Do you need help?</strong><br/>
2626                                             <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.
2627                                             <br/>
2628                                             <b>Switching this will reload the dashboard</b>.
2629                                             </small>
2630                                         </td>
2631                                         </tr>
2632                                     <tr class="option-row">
2633                                         <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>
2634                                         <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
2635                                             <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>
2636                                         </td>
2637                                         </tr>
2638                                     <tr class="option-row">
2639                                         <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle"  data-on="Smooth" data-off="Rough" data-width="110px"></td>
2640                                         <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
2641                                             <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.
2642                                             <br/>
2643                                             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>
2644                                         </td>
2645                                         </tr>
2646                                     </table>
2647                                 </div>
2648                             </form>
2649                         </div>
2650                     </div>
2651                 </div>
2652                 <div class="modal-footer">
2653                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2654                 </div>
2655             </div>
2656         </div>
2657     </div>
2658
2659
2660     <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
2661         <div class="modal-dialog" role="document">
2662             <div class="modal-content">
2663                 <div class="modal-header">
2664                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2665                     <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
2666                 </div>
2667                 <div class="modal-body">
2668                     Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
2669                     <br/>
2670                     <div style="padding: 10px;"></div>
2671                     <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
2672                 </div>
2673                 <div class="modal-footer">
2674                     <a href="#" onclick="notifyForUpdate(true); return false;" type="button" class="btn btn-default">Check Now</a>
2675                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2676                 </div>
2677             </div>
2678         </div>
2679     </div>
2680
2681     <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
2682         <div class="modal-dialog" role="document">
2683             <div class="modal-content">
2684                 <div class="modal-header">
2685                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2686                     <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
2687                 </div>
2688                 <div class="modal-body">
2689                     You are about to delete, from your personal list of netdata servers, the following server:
2690                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
2691                     <b><span id="deleteRegistryServerName2"></span></b>
2692                     <br/>
2693                     <b><span id="deleteRegistryServerURL"></span></b>
2694                     </p>
2695                     Are you sure you want to do this?
2696                     <br/>
2697                     <div style="padding: 10px;"></div>
2698                     <small>Keep in mind, this server will be added back if and when you visit it again.</small>
2699                     <br/>
2700                     <div id="deleteRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
2701                 </div>
2702                 <div class="modal-footer">
2703                     <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
2704                     <a href="#" onclick="notifyForDeleteRegistry(true); return false;" type="button" class="btn btn-danger">delete it</a>
2705                 </div>
2706             </div>
2707         </div>
2708     </div>
2709
2710     <div class="modal fade" id="switchRegistryModal" tabindex="-1" role="dialog" aria-labelledby="switchRegistryModalLabel">
2711         <div class="modal-dialog" role="document">
2712             <div class="modal-content">
2713                 <div class="modal-header">
2714                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2715                     <h4 class="modal-title" id="switchRegistryModalLabel">Switch Netdata Registry Identity</h4>
2716                 </div>
2717                 <div class="modal-body">
2718                     You can copy and paste the following ID to all your browsers (e.g. work and home).
2719                     <br/>
2720                     All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
2721                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
2722                     <form action="#">
2723                     <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
2724                     </form>
2725                     </p>
2726                     Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
2727                     <p style="padding-top: 10px;"><small>
2728                         Keep in mind that:
2729                         <ul>
2730                             <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li>
2731                             <li>both IDs (your old and the new) must list this netdata at their personal lists.</li>
2732                             <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li>
2733                             <li>to get a new ID, just clear your browser cookies.</li>
2734                         </ul>
2735                     </small></p>
2736                     <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
2737                 </div>
2738                 <div class="modal-footer">
2739                     <button type="button" class="btn btn-success" data-dismiss="modal">cancel</button>
2740                     <a href="#" onclick="notifyForSwitchRegistry(true); return false;" type="button" class="btn btn-danger">impersonate</a>
2741                 </div>
2742             </div>
2743         </div>
2744     </div>
2745
2746     <div class="modal fade" id="gotoServerModal" tabindex="-1" role="dialog" aria-labelledby="gotoServerModalLabel">
2747         <div class="modal-dialog" role="document">
2748             <div class="modal-content">
2749                 <div class="modal-header">
2750                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
2751                     <h4 class="modal-title" id="gotoServerModalLabel"><span id="gotoServerName"></span></h4>
2752                 </div>
2753                 <div class="modal-body">
2754                     Checking known URLs for this server...
2755                     <div  style="padding-top: 20px;">
2756                         <table id="gotoServerList">
2757                         </table>
2758                     </div>
2759                     <p style="padding-top: 10px;"><small>
2760                         Checks may fail if you are viewing an HTTPS page and the server to be checked is HTTP only.
2761                     </small></p>
2762                     <div id="gotoServerResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
2763                 </div>
2764                 <div class="modal-footer">
2765                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
2766                 </div>
2767             </div>
2768         </div>
2769     </div>
2770 </body>
2771 </html>
2772 <script async type="text/javascript" src="dashboard.js?v57"></script>