443408d92e71fd8f0df349be51915cbb2afb27b1
[dweather.git] / templates / index.html.ep
1 % my $url = url_for 'weather';
2 % my $s;
3 <!DOCTYPE html>
4 <html>
5         <head>
6                 <title>DWeather</title>
7                 <meta charset="utf-8">
8                 <meta http-equiv="X-UA-Compatible" content="IE=edge">
9                 <meta name="viewport" content="width=device-width, initial-scale=1">
10
11                 <!-- Latest compiled and minified CSS -->
12                 <link rel="stylesheet" href="css/bootstrap.min.css">
13
14                 <!-- Optional theme -->
15                 <link rel="stylesheet" href="css/bootstrap-theme.min.css">
16
17         </head>
18         <body>
19                 <center><h1>High View Weather</h1></center>
20
21                 <script>
22                 var ws;
23                 var daychart;
24                 var daychart_days = <%= $main::histdays %>;
25                 var windrose;
26                 var windrose_mins = <%= $main::windmins %>;
27                 var windspeed;
28                 var winddir;
29                 var updatespermin = <%= $main::updatepermin %>;
30
31                 var h = new Object();
32
33                 var trans = {
34                         "Wind" : function (speed) { return (speed * 2.236936).toFixed(1); },
35                         "Wind_1m" : function (speed) { return (speed * 2.236936).toFixed(1); },
36                         "Wind_Max": function (speed) { return (speed * 2.236936).toFixed(1); }
37                 };
38                         
39
40                 function do_debug(text) {
41                         document.getElementById("do_debug").innerHTML = text;
42                 }
43
44                 function update_h(key, value) {
45                         h[key] = value;
46                 }
47
48                 function fill_html(key,value) {
49                         var d = document.getElementById(key);
50                         if (d !== null) {
51                                 var f = trans[key];
52                                 if (f && typeof(f) === "function") {
53                                         d.innerHTML = trans[key](value);
54                                 } else {
55                                         d.innerHTML = value;
56                                 }
57                         }
58                 }
59
60                 function traverse(o, func) {
61                         console.log(o);
62                         for (var i in o) {
63                                 if (o[i] !== null && typeof(o[i])==="object") {
64                                         traverse(o[i], func);
65                                 } else {
66                                         func(i, o[i]);
67                                 }
68                         }
69                 }
70
71                 var lastwind = 0;
72                 var lastdir = 0;
73                 var lastt = 0;
74
75                 function startws() {
76                         ws = new WebSocket('<%= $url->to_abs %>');
77
78                         if (typeof(ws) !== null) {
79                                 ws.onmessage = function (event) {
80                                         var js = JSON.parse(event.data);
81                                         if (js !== null && typeof(js) === 'object') {
82                                                 traverse(js, fill_html);
83 //                                              traverse(js, update_h);
84 //                                              document.getElementById("hh").innerHTML = JSON.stringify(h);
85                                                 if ("h" in js) {
86                                                         fill_daychart(js, daychart_days);
87                                                 }
88                                                 if ("r" in js || "m" in js) {
89                                                         var rr;
90                                                         rr = js.r || js.m;
91                                                         if (!("Dir" in rr)) 
92                                                                 rr.Dir = lastdir;
93                                                         if (!("Wind" in rr))
94                                                                 rr.Wind = lastwind;
95                                                         fill_windrose(rr, windrose_mins * updatespermin);
96                                                         fill_windspeed(rr);
97                                                         fill_winddir(rr);
98                                                         lastwind = rr.Wind;
99                                                         lastdir = rr.Dir;
100                                                 }
101                                         }
102                                 };
103                                 ws.onopen = function (event) {
104                                         document.getElementById("wsconnect").innerHTML = 'ws connected to: <%= $url->to_abs %>';
105                                         ws.send('WebSocket support works!');
106                                 };
107                                 ws.onclose = function(event) {
108                                         document.getElementById("wsconnect").innerHTML = 'ws disconnected, refresh to restart';
109                                         ws = null;
110                                 }
111                         } else {
112                                 document.body.innerHTML += 'Webserver only works with Websocket aware browsers';
113                         }
114                 }
115
116                 function start_daychart() {
117                         daychart = new Highcharts.Chart({
118                                 chart: {
119                                         renderTo: 'daychart',
120                                         zoomType: 'xy'
121                                 },
122                                 title: {
123                                         text: 'Five Day Chart'
124                                 },
125                                 xAxis: [{
126                                         type: 'datetime',
127 //                                      categories: [],
128                                         crosshair: true
129                                 }],
130                                 yAxis: [{ // Primary yAxis
131                                         labels: {
132                                                 format: '{value}°C',
133                                                 style: {
134                                                         color: '#ff0000'
135                                                 }
136                                         },
137                                         title: {
138                                                 text: 'Temperature',
139                                                 style: {
140                                                         color: '#ff0000'
141                                                 }
142                                         },
143                                         opposite: true
144
145                                 }, { // Secondary yAxis
146                                         gridLineWidth: 0,
147                                         title: {
148                                                 text: 'Rainfall',
149                                                 style: {
150                                                         color: Highcharts.getOptions().colors[0]
151                                                 }
152                                         },
153                                         labels: {
154                                                 format: '{value} mm',
155                                                 style: {
156                                                         color: Highcharts.getOptions().colors[0]
157                                                 }
158                                         }
159
160                                 }, { // Tertiary yAxis
161                                         gridLineWidth: 0,
162                                         title: {
163                                                 text: 'Sea-Level Pressure',
164                                                 style: {
165                                                         color: Highcharts.getOptions().colors[1]
166                                                 }
167                                         },
168                                         labels: {
169                                                 format: '{value} mb',
170                                                 style: {
171                                                         color: Highcharts.getOptions().colors[1]
172                                                 }
173                                         },
174                                         opposite: true
175                                 }, { // Tertiary yAxis
176                                         gridLineWidth: 0,
177                                         floor: 0,
178                                         ceiling: 100,
179                                         title: {
180                                                 text: 'Humidity',
181                                                 style: {
182                                                         color: '#008800'
183                                                 }
184                                         },
185                                         labels: {
186                                                 format: '{value} %',
187                                                 style: {
188                                                         color: '#008800'
189                                                 }
190                                         },
191 //                                      opposite: true
192                                 }],
193                                 tooltip: {
194                                         shared: true
195                                 },
196                                 legend: {
197                                         layout: 'vertical',
198                                         align: 'left',
199                                         x: 120,
200                                         verticalAlign: 'top',
201                                         y: 55,
202                                         floating: true,
203                                         backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
204                                 },
205                                 exporting: {
206                                         buttons: {
207                                                 contextButton: {
208                                                         enabled: false
209                                                 }
210                                         }
211                                 }, 
212                                 series: [{
213                                         name: 'Rainfall',
214                                         type: 'column',
215                                         yAxis: 1,
216                                         labels: {
217 //                                              enabled: true,
218 //                                              format: '{point.y:.1f}', // one decimal
219 //                                              rotation: -90,
220                                                 overflow: 'justify'
221                                         },
222                                         data: [ 
223                                             <% $s = "";
224                                                    for (@main::last5daysh) { 
225                                                       my $r = $main::json->decode($_);
226                                                       $s .=  "[" . $r->{t}*1000 . "," . $r->{h}->{Rain_1h} . "]," if $r && exists $r->{t} && exists $r->{h}->{Rain_1h};
227                                                    }
228                                                    chop $s if length $s; 
229                                                 %><%= $s %>
230                                         ],
231                                         tooltip: {
232                                                 valueSuffix: ' mm'
233                                         }
234
235                                 }, {
236                                         name: 'Sea-Level Pressure',
237                                         type: 'spline',
238                                         yAxis: 2,
239                                         data: [
240                                                 <% $s = "";
241                                                    for (@main::last5daysh) { 
242                                                       my $r = $main::json->decode($_);
243                                                       $s .=  "[" . $r->{t}*1000 . "," . $r->{h}->{Pressure} . "]," if $r && exists $r->{t} && exists $r->{h}->{Pressure};
244                                                    }
245                                                    chop $s if length $s; 
246                                                 %><%= $s %>
247                                         ],
248                                         marker: {
249                                                 enabled: false
250                                         },
251                                         dashStyle: 'shortdot',
252                                         tooltip: {
253                                                 valueSuffix: ' mb'
254                                         }
255
256                                 }, {
257                                         name: 'Temperature',
258                                         type: 'spline',
259                                         yAxis: 0,
260                                         color: '#ff0000',
261                                         data: [
262                                                 <% $s = "";
263                                                    for (@main::last5daysh) { 
264                                                       my $r = $main::json->decode($_);
265                                                       $s .=  "[" . $r->{t}*1000 . "," . $r->{h}->{Temp_Out} . "]," if $r && exists $r->{t} && exists $r->{h}->{Temp_Out};
266                                                    }
267                                                    chop $s if length $s; 
268                                                 %><%= $s %>
269                                         ],
270                                         tooltip: {
271                                                 valueSuffix: ' °C'
272                                         }
273                                 }, {
274                                         name: 'Humidity',
275                                         type: 'spline',
276                                         color: '#008800',
277                                         yAxis: 3,
278                                         data: [
279                                                 <% $s = "";
280                                                    for (@main::last5daysh) { 
281                                                       my $r = $main::json->decode($_);
282                                                       $s .=  "[" . $r->{t}*1000 . "," . $r->{h}->{Humidity_Out} . "]," if $r && exists $r->{t} && exists $r->{h}->{Humidity_Out};
283                                                    }
284                                                    chop $s if length $s; 
285                                                 %><%= $s %>
286                                         ],
287                                         marker: {
288                                                 enabled: false
289                                         },
290                                         dashStyle: 'shortdot',
291                                         tooltip: {
292                                                 valueSuffix: ' %'
293                                         }
294                                 }]
295                         });
296                 }
297
298                 function start_windrose() {
299
300                         // Load the fonts
301                         Highcharts.createElement('link', {
302                                 href: '//fonts.googleapis.com/css?family=Dosis:400,600',
303                                 rel: 'stylesheet',
304                                 type: 'text/css'
305                         }, null, document.getElementsByTagName('head')[0]);
306
307                         Highcharts.theme = {
308                                 colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
309                                         "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
310                                 chart: {
311                                         backgroundColor: null,
312                                         style: {
313                                                 fontFamily: "Dosis, sans-serif"
314                                         }
315                                 },
316                                 title: {
317                                         style: {
318                                                 fontSize: '16px',
319                                                 fontWeight: 'bold',
320                                                 textTransform: 'uppercase'
321                                         }
322                                 },
323                                 tooltip: {
324                                         borderWidth: 0,
325                                         backgroundColor: 'rgba(219,219,216,0.8)',
326                                         shadow: false
327                                 },
328                                 legend: {
329                                         itemStyle: {
330                                                 fontWeight: 'bold',
331                                                 fontSize: '13px'
332                                         }
333                                 },
334                                 xAxis: {
335                                         gridLineWidth: 1,
336                                         labels: {
337                                                 style: {
338                                                         fontSize: '12px'
339                                                 }
340                                         }
341                                 },
342                                 yAxis: {
343                                         minorTickInterval: 'auto',
344                                         title: {
345                                                 style: {
346                                                         textTransform: 'uppercase'
347                                                 }
348                                         },
349                                         labels: {
350                                                 style: {
351                                                         fontSize: '12px'
352                                                 }
353                                         }
354                                 },
355                                 plotOptions: {
356                                         candlestick: {
357                                                 lineColor: '#404048'
358                                         }
359                                 },
360
361
362                                 // General
363                                 background2: '#F0F0EA'
364                                 
365                         };
366
367                         // Apply the theme
368                         Highcharts.setOptions(Highcharts.theme);
369
370                         windrose = new Highcharts.Chart({
371                                 chart: {
372                                         polar: true,
373                                         renderTo: 'windrose'
374                                 },
375                                 
376                                 title: {
377                                         text: 'Wind Rose'
378                                 },
379                                 
380                                 pane: {
381                                         startAngle: 0,
382                                         endAngle: 360
383                                 },
384
385                                 xAxis: {
386                                         tickInterval: 15,
387                                         min: 0,
388                                         max: 360,
389                                         labels: {
390                                                 formatter: function () {
391                                                         return this.value + '°';
392                                                 }
393                                         }
394                                 },
395
396                                 yAxis: {
397                                         min: 0
398                                 },
399
400                                 plotOptions: {
401                                         series: {
402                                                 pointStart: 0,
403                                                 pointInterval: 15
404                                         },
405                                         column: {
406                                                 pointPadding: 0,
407                                                 groupPadding: 0
408                                         }
409                                 },
410                                 exporting: {
411                                         buttons: {
412                                                 contextButton: {
413                                                         enabled: false
414                                                 }
415                                         }
416                                 }, 
417
418                                 series: [ {
419                                         type: 'scatter',
420                                         name: 'Wind mph',
421                                         data: [
422                                                 <% my ($d, $w);
423                                                    $s = "";
424                                                    $d = 0; $w = 0;
425                                                for (@main::last10minsr) {
426                                                       my $r = $main::json->decode($_);
427                                                           if ($r) {
428                                                                   $r->{r}->{Dir} ||= $d;
429                                                                   $r->{r}->{Wind} ||= $w;
430                                                                   $s .=  "[" . $r->{r}->{Dir} . "," . main::nearest(0.1, $r->{r}->{Wind}*2.23694) . "],";
431                                                                   $d = $r->{r}->{Dir};
432                                                                   $w = $r->{r}->{Wind};
433                                                           }
434                                                    } 
435                                                    chop $s if length $s; 
436                                                 %><%= $s %>
437                                         ]
438                                 }]
439                         });
440                 }
441
442                 function start_windspeed() {
443                         windspeed = new Highcharts.Chart({
444                                 chart: {
445                                         type: 'gauge',
446                                         renderTo: 'windspeed',
447                                         plotBackgroundColor: null,
448                                         plotBackgroundImage: null,
449                                         plotBorderWidth: 0,
450                                         plotShadow: false
451                                 },
452
453                                 title: {
454                                         text: 'Wind Speed'
455                                 },
456
457                                 pane: {
458                                         startAngle: -150,
459                                         endAngle: 150,
460                                         background: [{
461                                                 backgroundColor: {
462                                                         linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
463                                                         stops: [
464                                                                 [0, '#FFF'],
465                                                                 [1, '#333']
466                                                         ]
467                                                 },
468                                                 borderWidth: 0,
469                                                 outerRadius: '109%'
470                                         }, {
471                                                 backgroundColor: {
472                                                         linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
473                                                         stops: [
474                                                                 [0, '#333'],
475                                                                 [1, '#FFF']
476                                                         ]
477                                                 },
478                                                 borderWidth: 1,
479                                                 outerRadius: '107%'
480                                         }, {
481                                                 // default background
482                                         }, {
483                                                 backgroundColor: '#DDD',
484                                                 borderWidth: 0,
485                                                 outerRadius: '105%',
486                                                 innerRadius: '103%'
487                                         }]
488                                 },
489
490                                 // the value axis
491                                 yAxis: {
492                                         min: 0,
493                                         max: 50,
494
495                                         minorTickInterval: 'auto',
496                                         minorTickWidth: 1,
497                                         minorTickLength: 10,
498                                         minorTickPosition: 'inside',
499                                         minorTickColor: '#666',
500
501                                         tickPixelInterval: 30,
502                                         tickWidth: 2,
503                                         tickPosition: 'inside',
504                                         tickLength: 10,
505                                         tickColor: '#666',
506                                         labels: {
507                                                 step: 2,
508                                                 rotation: 'auto'
509                                         },
510                                         title: {
511                                                 text: 'mph'
512                                         },
513                                         plotBands: [{
514                                                 from: 0,
515                                                 to: 15,
516                                                 color: '#55BF3B' // green
517                                         }, {
518                                                 from: 16,
519                                                 to: 29,
520                                                 color: '#DDDF0D' // yellow
521                                         }, {
522                                                 from: 30,
523                                                 to: 50,
524                                                 color: '#DF5353' // red
525                                         }]
526                                 },
527                                 exporting: {
528                                         buttons: {
529                                                 contextButton: {
530                                                         enabled: false
531                                                 }
532                                         }
533                                 }, 
534
535                                 series: [{
536                                         name: 'Speed',
537                                         data: [0],
538                                         tooltip: {
539                                                 valueSuffix: ' mph'
540                                         }
541                                 }]
542                         });
543                 }
544
545                 function start_winddir() {
546                         winddir = new Highcharts.Chart({
547                                 chart: {
548                                         type: 'gauge',
549                                         renderTo: 'winddir',
550                                         plotBackgroundColor: null,
551                                         plotBackgroundImage: null,
552                                         plotBorderWidth: 0,
553                                         plotShadow: false
554                                 },
555
556                                 title: {
557                                         text: 'Wind Direction'
558                                 },
559
560                                 pane: {
561                                         startAngle: 0,
562                                         endAngle: 360,
563                                         background: [{
564                                                 backgroundColor: {
565                                                         linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
566                                                         stops: [
567                                                                 [0, '#FFF'],
568                                                                 [1, '#333']
569                                                         ]
570                                                 },
571                                                 borderWidth: 0,
572                                                 outerRadius: '109%'
573                                         }, {
574                                                 backgroundColor: {
575                                                         linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
576                                                         stops: [
577                                                                 [0, '#333'],
578                                                                 [1, '#FFF']
579                                                         ]
580                                                 },
581                                                 borderWidth: 1,
582                                                 outerRadius: '107%'
583                                         }, {
584                                                 // default background
585                                         }, {
586                                                 backgroundColor: '#DDD',
587                                                 borderWidth: 0,
588                                                 outerRadius: '105%',
589                                                 innerRadius: '103%'
590                                         }]
591                                 },
592
593                                 // the value axis
594                                 yAxis: {
595                                         min: 0,
596                                         max: 359,
597
598                                         minorTickInterval: 'auto',
599                                         minorTickWidth: 1,
600                                         minorTickLength: 10,
601                                         minorTickPosition: 'inside',
602                                         minorTickColor: '#666',
603
604                                         tickPixelInterval: 15,
605                                         tickWidth: 2,
606                                         tickPosition: 'inside',
607                                         tickLength: 10,
608                                         tickColor: '#666',
609                                         labels: {
610                                                 step: 2,
611                                                 rotation: 'auto'
612                                         },
613                                         title: {
614                                                 text:  '° deg'
615                                         },
616                                 },
617                                 exporting: {
618                                         buttons: {
619                                                 contextButton: {
620                                                         enabled: false
621                                                 }
622                                         }
623                                 }, 
624
625                                 series: [{
626                                         name: 'Direction',
627                                         data: [0],
628                                         tooltip: {
629                                                 valueSuffix: ' ° deg'
630                                         }
631                                 }]
632                         });
633                 }
634
635                 function fill_daychart(js, days) {
636                         var rainfall = daychart.series[0].data.length > (days * 48);
637                         var pressure = daychart.series[1].data.length > (days * 48);
638                         var temp = daychart.series[2].data.length > (days * 48);
639                         var humidity = daychart.series[3].data.length > (days * 48);
640
641                         var hr = js.h;
642                         var t = js.t * 1000;
643                         var ra = [t, hr.Rain_1h];
644                         var pr = [t, hr.Pressure];
645                         var te = [t, hr.Temp_Out];
646                         var hu = [t, hr.Humidity_Out];
647                                 
648 //                      do_debug(js.tm + " " + t + " " + te + "<br>"); 
649                         daychart.series[0].addPoint(ra, true, rainfall);
650                         daychart.series[1].addPoint(pr, true, pressure);
651                         daychart.series[2].addPoint(te, true, temp);
652                         daychart.series[3].addPoint(hu, true, humidity);
653                 }
654
655                 var conv = 2.23694;
656
657                 function fill_windrose(rr, points) {
658                         var p = windrose.series[0].data.length > points;
659                         var v = [rr.Dir, (rr.Wind*conv)];
660                         windrose.series[0].addPoint(v, true, p);
661                 }
662
663                 function fill_windspeed(rr) {
664                         var point = windspeed.series[0].points[0];
665                         point.update(Math.round(rr.Wind*conv));
666                 }
667
668                 function fill_winddir(rr) {
669                         var point = winddir.series[0].points[0];
670                         point.update(rr.Dir);
671                 }
672
673                 window.onload = function() {
674                         startws();
675                         start_daychart();
676                         start_windrose();
677                         start_windspeed();
678                         start_winddir();
679                         window.setInterval(function() {
680                                 if (ws === null)
681                                         startws();
682                         }, 15000);
683                 }
684
685                 </script>
686
687                 <div id="container">
688                         <div id="daychart" style="min-width: 400px; height: 400px; margin: 0 auto"> </div>
689                 </div>
690
691                 <div id="container">
692                         <table border="0" align="center">
693                                 <tr>
694                                         <td id="windrose" style="min-width: 350px; max-width: 400px; height: 330px; margin: 0 auto"> </td>
695                                         <td id="windspeed" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
696                                         <td id="winddir" style="min-width: 280px; max-width: 400px; height: 270px; margin: 0 auto"> </td>
697                                 </tr>
698                         </table>
699                 </div>
700
701                 <div id="container">
702                         <div id="start-template">
703                                 <br><br>
704                                 <table class="table">
705                                         <tr>
706                                                 <th width="7%">Time:</th><td width="7%"><span id="tm"> </span></td>
707                                                 <th width="7%">Sunrise:</th><td width="7%"><span id="Sunrise"> </span></td>
708                                                 <th width="7%">Sunset:</th><td width="7%"><span id="Sunset"> </span></td>
709                                                 <th width="7%">Console Volts:</th><td width="7%"><span id="Batt_Console"> </span></td>
710                                                 <th width="7%">TX Battery OK:</th><td width="7%"><span id="Batt_TX_OK"> </span></td>
711                                         </tr>
712                                         <tr>
713                                                 <th>Pressure:</th><td><span id="Pressure"> </span> mb</td>
714                                                 <th>Trend:</th><td><span id="Pressure_Trend_txt"> </span></td>
715                                         </tr>
716                                         <tr>
717                                                 <th>Temperature in:</th><td> <span id="Temp_In"> </span> °C</td>
718                                                 <th>Humidity:</th><td> <span id="Humidity_In"> </span> %</td>
719                                         </tr>
720                                         <tr><th>Temperature out:</th><td> <span id="Temp_Out"> </span> °C</td>
721                                                 <th>Min:</th><td> <span id="Temp_Out_Min"> </span> °C @ <span id="Temp_Out_Min_T"> </span></td>
722                                                 <th>Max:</th><td> <span id="Temp_Out_Max"> </span> °C @ <span id="Temp_Out_Max_T"> </span></td>
723                                                 <th>Humidity:</th><td> <span id="Humidity_Out"> </span> %</td>
724                                                 <th>Dew Point:</th><td> <span id="Dew_Point"> </span> °C</td>
725                                         </tr>
726                                         <tr><th>Wind:</th><td><span id="Dir"> </span> ° @ <span id="Wind"> </span> mph</td>
727                                                 <th>Wind Minute Avg:</th><td> <span id="Dir_1m"> </span> ° @ <span id="Wind_1m"> </span> mph </td>
728                                                 <th>Day Max Speed:</th><td> <span id="Wind_Max"> </span> mph @ <span id="Wind_Max_T"> </span></td>
729                                         </tr>
730                                         <tr>
731                                                 <th>Rain 30mins:</th><td> <span id="Rain_1h"> </span> mm</td>
732                                                 <th>Day:</th><td> <span id="Rain_Day"> </span> mm</td>
733                                                 <th>24hrs:</th><td> <span id="Rain_24h"> </span> mm</td>
734                                                 <th>Month:</th><td> <span id="Rain_Month"> </span> mm</td>
735                                                 <th>Year:</th><td> <span id="Rain_Year"> </span> mm</td>
736                                         </tr>
737                                 </table>
738                         </div>
739                 </div>
740
741
742                 <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
743                 <script src="js/jquery.min.js"></script>
744                 <!-- Latest compiled and minified JavaScript -->
745                 <script src="js/bootstrap.min.js"></script>
746                 <!-- High Chart stuff -->
747                 <script src="js/highcharts.js"></script>
748                 <script src="js/highcharts-more.js"></script>
749                 <script src="js/modules/exporting.js"></script>
750
751         </body>
752 </html>