text:
/*!
 * sharedmemo
 * https://github.com/masakick/sharedmemo
 */

sharedtext = function(){

	//ミルクココアインスタンスを作成
    milkcocoa = new MilkCocoa("https://io-ri1inr81p.mlkcca.com");

	//"message"データストアを作成
    dsMessage = milkcocoa.DataStore("message");

    var models = {
	    message: {
			id:null,
			date:null,
			title:null,
			content:null,
			isSaved:null
		},

		init:function(){
			models.message.id = models.message.isSaved = models.message.date = models.message.title = models.message.text = null;
		},

		post:function() {
            dsMessage.push({
                	title: models.message.title,
					content: models.message.content,
					date: models.getUtcDateString()
            	},
            	function (e) {
	            	views.callbackPost(e);
	            });
	    },

	    set:function() {
            dsMessage.set(models.message.id,{
                	title: models.message.title,
					content: models.message.content,
					date: models.getUtcDateString()
					},
					function(e){
						views.callbackSet(e);
					});
	    },

	    remove:function(){
			if(models.message.id){
			  dsMessage.remove(models.message.id);
			}
	    },

	    getUtcDateString:function(){
		    var date = new Date();
		    var year = date.getUTCFullYear();
		    var month = date.getUTCMonth();
		    var day = date.getUTCDay();
		    var hour = date.getUTCHours();
		    var min = date.getUTCMinutes();
		    var sec = date.getUTCSeconds();
		    var utcString = year+','+month+','+day+','+hour+','+min+','+sec;
		    return utcString;
	    }

	}
    , views = {
	    init: function(){
			models.init();
			/* events */
			$(window).hashchange( function(){
		    	views.hashChange();
			});

		    dsMessage.on('set', function(data) {

			});

			dsMessage.on('push', function(data) {

			});

			dsMessage.on('remove', function(data) {

				location.hash = "/messages";
			});

			views.load();
		},

		load: function(){

			var hash = location.hash;
			var viewName = hash.split("/")[1];

			switch(viewName){
				case "messages":
				views.showMessages();
				break;

				case "new":
				views.showNew();
				break;

				case "message":
				models.message.id = hash.split("/")[2];
				views.showMessage();
				break;

				case "edit":
				models.message.id = hash.split("/")[2];
				views.showEdit();
				break;

				default:
				views.showMessages();
				break;
			}
		},

		hashChange: function(){
		      views.load();
		},

	    showMessages:function(){

			//"message"データストアからメッセージを取ってくる
			dsMessage.query({}).sort("desc").done(function(e) {
	        	e.forEach(function(message) {
	            	var message_html = '
'
	            					+'
'+ escapeHTML(message.title)+'
'
	            					+'
'+ escapeHTML(message.content)
	            					+'
'+views.toLocaleString(message.date)+ '
'
	            					+'

';
			        $("#messages").append(message_html);
	        	});

	    	});

	    	$("#nav-all").addClass("active");
	    	$("#nav-new").removeClass("active");
	    	$("#message").empty();
			$('#postarea').empty();

		},

		showNew:function(){
			models.message.id = null;
			var inner_html = '

'
						+'
'
						+'<input type="text" id="ms-title" class="form-control" placeholder="タイトル">'
						+'<textarea id="ms-text" class="form-control" rows="10"placeholder="何か書く"></textarea>'
						+'
'
						+'<button id="post" type="button" class="btn btn-default btn-sm"> Save</button> '
						+'<button id="remove" type="button" class="btn btn-danger btn-sm"> Delete</button>'
						+'
';
			$('#postarea').html(inner_html);

			$('#post').click(function () {
				$(this).attr('disabled','disabled');
				models.message.title = escapeHTML($("#ms-title").val());
	        	models.message.content = escapeHTML($("#ms-text").val());
				models.post();

		    });

		    $("#nav-new").addClass("active");
	    	$("#nav-all").removeClass("active");
			$('#messages').empty();
			$('#message').empty();
		},

		showMessage : function(){

		    dsMessage.get(models.message.id,function(message) {

			    var innter_html = '
' + escapeHTML(message.title) + '
'
			    				 + '
' + escapeHTML(message.content) + '
'
								 + '
'+views.toLocaleString(message.date)+'
'
								 + '<button type="button" class="btn btn-default btn-sm" id="btn_edit"> Edit</button>';
		        $("#message").html(innter_html);
		        $("#btn_edit").click(function(){
			        location.hash = "/edit/"+message.id;
		        });
			});
			$("#nav-all").removeClass("active");
	    	$("#nav-new").removeClass("active");
			$('#messages').empty();
			$('#postarea').empty();
		},

		showEdit : function(){
		    dsMessage.get(models.message.id,function(message) {

				var inner_html = '
Saved at '+views.toLocaleString(message.date)+'
'
							+ '
'
							+'<input type="text" id="ms-title" class="form-control" placeholder="Text input" value="'+message.title+'">'
							+'<textarea id="ms-text" class="form-control" rows="10">'+message.content+'</textarea>'
							+'
'
							+'<button id="post" type="button" class="btn btn-default btn-sm"> Save</button> '
							+'<button id="remove" type="button" class="btn btn-danger btn-sm"> Delete</button>'
							+'
';
				$('#postarea').html(inner_html);
				$('#post').click(function () {
					models.message.title = escapeHTML($("#ms-title").val());
		        	models.message.content = escapeHTML($("#ms-text").val());
					if(models.message.id != null){
						$(this).attr('disabled','disabled');
						models.set();
					}
			    });
			    $('#remove').click(function () {

					models.remove();
			    });
			});
			$("#nav-all").removeClass("active");
	    	$("#nav-new").removeClass("active");
			$('#messages').empty();
			$('#message').empty();
		},

		callbackPost:function(data){

			if(data.error!='null'){
				//success
	            location.hash = "/edit/"+data.id;
			}
			else{
				//fail
				alert('saveできませんでした。/n'+data.error);

			}
			$('#post').removeAttr('disabled');

		},
		callbackSet:function(data){

			if(data.error!='null'){
				//success
				dsMessage.get(data.id,function(message) {
	            	$('#ms-postdate').html(views.toLocaleString(message.date));
	            });
			}
			else{
				//fail
				alert('saveできませんでした。/n'+data.error);

			}
			$('#post').removeAttr('disabled');
		},
		toLocaleString:function(str){
			var d = new Date();
			d.setTime(eval("Date.UTC("+str+")"));
			return d.toLocaleString();
		}

      }
    , controllers = {}

	views.init();

};

$(function() {

	sharedtext = new sharedtext();
});
function escapeHTML(val) {
    return $('
').text(val).html();
};


text:
class User < ActiveRecord::Base
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  attr_accessible :email, :password, :password_confirmation, :remember_me
end

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

    <title>Draw Feature Example</title>
    <meta charset="utf-8">
    <meta name="viewport"
          content="initial-scale=1.0, user-scalable=no, width=device-width">
    <meta name="mobile-web-app-capable" content="yes">
    <link rel="stylesheet" href="../../../node_modules/openlayers/css/ol.css" type="text/css">
    <link rel="stylesheet" href="../../../node_modules/bootstrap/dist/css/bootstrap.css" type="text/css">
    <link rel="stylesheet" href="../../../node_modules/font-awesome/css/font-awesome.css" type="text/css">
    <link rel="stylesheet" href="../../../third-party/jquery-ui/jquery-ui.min.css">

    <gmf-map gmf-map-map="::ctrl.map"></gmf-map>

    <input type="checkbox"
       id="checkbox-drawfeature"
       ng-model="ctrl.drawFeatureActive" />
     DrawFeature

    <input type="checkbox"
       id="checkbox-pointermove"
       ng-model="ctrl.pointerMoveActive" />
     PointerMove

Draw & Measure

    <gmf-drawfeature
      ng-show="ctrl.drawFeatureActive === true"
      gmf-drawfeature-active="ctrl.drawFeatureActive"
      gmf-drawfeature-map="::ctrl.map">
    </gmf-drawfeature>

      This example shows how to use the gmf-drawfeature
      directive to create, modify and delete vector features on a map and
      style them as we please.


text:
function replaceNumbers(string) {
    return string.replace(/0/g, 'z').replace(/1/g, 'a').replace(/2/g, 'b').replace(/3/g, 'c').replace(/4/g, 'd').replace(/5/g, 'e').replace(/6/g, 'f').replace(/7/g, 'g').replace(/8/g, 'h').replace(/9/g, 'i')
};

// List of all loaded host IP addresses used to not load already loaded charts
var loaded_hosts = []
// Check if given host IP address is already loaded (stored in loaded list)
function isHostLoaded(host_ip) {
    return ((jQuery.inArray(host_ip, loaded_hosts) >= 0) ? true : false);
};
// Add given host IP address to already loaded host IPs list
function addLoadedHost(host_ip) {
    loaded_hosts.push(host_ip);
};
// Remove given host IP address from already loaded host IPs
function removeLoadedHost(host_ip) {
   loaded_hosts.splice($.inArray(host_ip, loaded_hosts), 1);
};

// Common function to store value of given name to cookie
function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
    var expires = "expires="+d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
};

// Common function to get value of given name from stored cookie
function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
};

//------------------- Page Control Functions -------------------
// Close chart panel for given host IP address
function closePanel(host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));
    // Get id of element to remove
    var element_id = '#' + host_id + '-charts-panel';

    // Remove specified panel
    $(element_id).remove();

    // Remove host IP from loaded IPs
    removeLoadedHost(host_ip);
};

//------------------- Heatmap Chart --------------------------
// Generate the histogram chart
function generateHeatmap(data) {
    // Heatmap ID
    var chartId = 'chart-host-heatmap';
    var chartIdStatus = chartId + '-status';

    // Get network prefix
    var network = $('#network').val().split('.');
    var network_prefix = network[0] + '.' + network[1] + '.';

    $('#' + chartId).highcharts({
        data: {
            csv: data
        },
        chart: {
            type: 'heatmap',
            zoomType: 'xy'
        },
        title: {
             text: '',
             style: {
                marginTop: '20px',
            },
        },
        xAxis: {
            type: 'linear',
            title:{
                text: "D segment of IP address"
            },
            tickInterval: 1
        },
        yAxis: {
            type: 'linear',
            title:{
                text: "C segment of IP address"
            },
            tickInterval: 4
        },
        colorAxis: {
            stops: [
                [0, '#ffffff'],
                [0.001, '#3060cf'],
                [0.01, '#c4463a'],
                [0.1, '#c4463a'],
                [1, '#000000']
            ],
            min: 0,
            max: 50000,
            startOnTick: false,
            endOnTick: false,
            labels: {
                format: '{value}'
            }
        },
        exporting: {
            enabled: false
        },
        tooltip: {
            enabled: true
        },
        plotOptions: {
                series: {
                    cursor: 'crosshair',
                    point: {
                        events: {
                            click: function (e) {
                                // Show details about selected host
                                var host_ip = network_prefix + this.y + "." + this.x;
                                loadHostCharts(host_ip);
                            }
                        }
                    },
                    marker: {
                        enabled: true,
                        lineWidth: 1
                    }
                }
        },
        series: [{
            borderWidth: 0,
            nullColor: '#EFEFEF',
            tooltip: {
                headerFormat: 'Host IP Address
',
                pointFormat: network_prefix + '{point.y}.{point.x} – {point.value} flows'
            },
            turboThreshold: Number.MAX_VALUE // #3404, remove after 4.0.5 release
        }]
    });

    // Hide status element
    $('#' + chartIdStatus).hide();
    // Show chart element
    $('#' + chartId).show();
    // Reflow chart to fit into parent element
    $('#' + chartId).highcharts().reflow();
};

// Obtain histogram data and generate the chart
function loadHeatmapChart() {
    // Elements ID
    var chartId = '#chart-host-heatmap';
    var chartIdStatus = chartId + '-status';

    // Hide chart element
    $(chartId).hide();
    // Show status element
    $(chartIdStatus).show();

    // Clear loaded hosts list
    $('#detailed-charts').empty();
    loaded_hosts = [];

    // Check if network is set in value or in cookie
    if ($('#network').val()) {
        // Save network to the cookie
        setCookie("host_statistics-network", $('#network').val(), 365)
    } else {
        // Check if network is stored in a cookie
        var network = getCookie("host_statistics-network");
        if (network != "") {
            // Set network stored in cookie and continue
            $('#network').val(network);
        } else {
            // If network is not set and not stored in cookie then show warning message
            $(chartIdStatus).html(
                '\
                 Network is not set!'
            )
            // Do not generate the heatmap if network is not set
            return;
        }
    }

    // Set loading status
    $(chartIdStatus).html(
        '\
         Loading...'
    )

    // Convert times to UTC in ISO format
    var beginning = new Date( $('#datetime-beginning').val()).toISOString();
    var end = new Date( $('#datetime-end').val()).toISOString();

    // Get network value (if empty then set "none")
    var network = $('#network').val() ? $('#network').val() : 'none';

    // Set data request
    var data_request = encodeURI( './get_heatmap_statistics' + '?beginning=' + beginning + '&end=' + end + '&network=' + network);
    // Get Elasticsearch data
    $.ajax({
        async: true,
        type: 'GET',
        url: data_request,
        success: function(raw) {
            var response = jQuery.parseJSON(raw);
            if (response.status == "Ok") {
                // Replace separator ';' to new line to create a CSV string and generate the heatmap
                generateHeatmap(response.data.replace(/;/g,'\n'));
            } else {
                // Show error message
                $(chartIdStatus).html(
                    '\
                     ' + response.status + ': ' + response.data + ''
                )
            }
        }
    });
};

//------------------- Host Network Traffic Chart --------------------------
// Generate a chart and set it to the given div
function generateHostFlowsChart(data, host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = host_id + '-flows';
    var chartIdStatus = chartId + '-status';

    // Hide status element
    $('#' + chartIdStatus).hide();
    // Show chart element
    $('#' + chartId).show();

    // ZingChart configuration
    var myConfig = {
        type: 'line',
        backgroundColor:'#fff',
        title:{
            text: 'Traffic Statistics of the Host ' + host_ip,
            adjustLayout: true,
            fontColor:"#444444"
        },
        legend:{
            align: 'center',
            verticalAlign: 'top',
            backgroundColor:'none',
            borderWidth: 0,
            item:{
                fontColor:'#444444',
                cursor: 'hand'
            },
            marker:{
                type:'circle',
                borderWidth: 0,
                cursor: 'hand'
            },
            toggleAction: 'remove'
        },
        plotarea:{
            margin:'dynamic 70'
        },
        plot:{
            lineWidth: 2,
            marker:{
                borderWidth: 0,
                size: 3
            }
        },
        scaleX:{
            lineColor: '#444444',
            zooming: true,
            item:{
                fontColor:'#444444'
            },
            transform:{
                type: 'date',
                all: '%D %M %d
%h:%i:%s'
            },
            label:{
                text: 'Time',
                visible: false
            }
        },
        scaleY:{
            minorTicks: 1,
            lineColor: '#444444',
            tick:{
                lineColor: '#444444'
            },
            minorTick:{
                lineColor: '#444444'
            },
            minorGuide:{
                visible: false
            },
            guide:{
                lineStyle: 'dashed'
            },
            item:{
                fontColor:'#444444'
            },
            short: true
        },
        tooltip:{
            borderWidth: 0,
            borderRadius: 3
        },
        preview:{
            adjustLayout: true,
            y: '85%',
            borderColor:'#444444',
            borderWidth: 1,
            mask:{
                backgroundColor:'#658687'
            }
        },
        crosshairX:{
            plotLabel:{
                multiple: true,
                borderRadius: 3
            },
            scaleLabel:{
                backgroundColor:'#373f47',
                borderRadius: 3
            },
            marker:{
                size: 7,
                alpha: 0.5
            }
        },
        csv:{
            dataString: data,
            rowSeparator: ';',
            separator: ',',
            verticalLabels: true
        }
    };

    // Render ZingChart with width based on the whole panel
    zingchart.render({
	    id: chartId,
	    data: myConfig,
	    height: $('#' + host_id + '-panels').height(),
	    width: $('#' + host_id + '-panels').width()
    });
};

// Obtain flow data for a host and generate the chart
function loadHostFlowsChart(host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = '#' + host_id + '-flows';
    var chartIdStatus = chartId + '-status';

    // Hide chart element
    $(chartId).hide();
    // Show status element
    $(chartIdStatus).show();

    // Set loading status
    $(chartIdStatus).html(
        '\
         Loading...'
    )

    // Convert times to UTC in ISO format
    var beginning = new Date( $('#datetime-beginning').val()).toISOString();
    var end = new Date( $('#datetime-end').val()).toISOString();

    // Set data request
    var data_request = encodeURI( './get_host_flows' + '?beginning=' + beginning + '&end=' + end + '&aggregation=' + $('#aggregation').val() + '&host_ip=' + host_ip);
    // Get Elasticsearch data
    $.ajax({
        async: true,
        type: 'GET',
        url: data_request,
        success: function(raw) {
            var response = jQuery.parseJSON(raw);
            if (response.status == "Ok") {
                generateHostFlowsChart(response.data, host_ip);
            } else {
                // Show error message
                $(chartIdStatus).html(
                    '\
                     ' + response.status + ': ' + response.data + ''
                )
            }
        }
    });
};

//------------------- Host Tcp Chart --------------------------
// Generate a chart and set it to the given div
function generateHostTcp(data, host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = host_id + '-tcp-flags';
    var chartIdStatus = chartId + '-status';

    // Hide status element
    $('#' + chartIdStatus).hide();
    // Show chart element
    $('#' + chartId).show();

    // ZingChart configuration
    var myConfig = {
        type: 'line',
        backgroundColor:'#fff',
        title:{
            text: 'TCP Flags of the Host ' + host_ip,
            adjustLayout: true,
            fontColor:"#444444"
        },
        legend:{
            align: 'center',
            verticalAlign: 'top',
            backgroundColor:'none',
            borderWidth: 0,
            item:{
                fontColor:'#444444',
                cursor: 'hand'
            },
            marker:{
                type:'circle',
                borderWidth: 0,
                cursor: 'hand'
            },
            toggleAction: 'remove'
        },
        plotarea:{
            margin:'dynamic 70'
        },
        plot:{
            lineWidth: 2,
            marker:{
                borderWidth: 0,
                size: 3
            }
        },
        scaleX:{
            lineColor: '#444444',
            zooming: true,
            item:{
                fontColor:'#444444'
            },
            transform:{
                type: 'date',
                all: '%D %M %d
%h:%i:%s'
            },
            label:{
                text: 'Time',
                visible: false
            }
        },
        scaleY:{
            minorTicks: 1,
            lineColor: '#444444',
            tick:{
                lineColor: '#444444'
            },
            minorTick:{
                lineColor: '#444444'
            },
            minorGuide:{
                visible: false
            },
            guide:{
                lineStyle: 'dashed'
            },
            item:{
                fontColor:'#444444'
            },
            short: true
        },
        tooltip:{
            borderWidth: 0,
            borderRadius: 3
        },
        preview:{
            adjustLayout: true,
            y: '85%',
            borderColor:'#444444',
            borderWidth: 1,
            mask:{
                backgroundColor:'#658687'
            }
        },
        crosshairX:{
            plotLabel:{
                multiple: true,
                borderRadius: 3
            },
            scaleLabel:{
                backgroundColor:'#373f47',
                borderRadius: 3
            },
            marker:{
                size: 7,
                alpha: 0.5
            }
        },
        csv:{
            dataString: data,
            rowSeparator: ';',
            separator: ',',
            verticalLabels: true
        }
    };

    // Render ZingChart with width based on the whole panel
    zingchart.render({
	    id: chartId,
	    data: myConfig,
	    height: $('#' + host_id + '-panels').height(),
	    width: $('#' + host_id + '-panels').width()
    });
};

// Obtain flow data for a host and generate the chart
function loadHostTcpChart(host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = '#' + host_id + '-tcp-flags';
    var chartIdStatus = chartId + '-status';

    // Hide chart element
    $(chartId).hide();
    // Show status element
    $(chartIdStatus).show();

    // Set loading status
    $(chartIdStatus).html(
        '\
         Loading...'
    )

    // Convert times to UTC in ISO format
    var beginning = new Date( $('#datetime-beginning').val()).toISOString();
    var end = new Date( $('#datetime-end').val()).toISOString();

    // Set data request
    var data_request = encodeURI( './get_host_tcp_flags' + '?beginning=' + beginning + '&end=' + end + '&aggregation=' + $('#aggregation').val() + '&host_ip=' + host_ip);
    // Get Elasticsearch data
    $.ajax({
        async: true,
        type: 'GET',
        url: data_request,
        success: function(raw) {
            var response = jQuery.parseJSON(raw);
            if (response.status == "Ok") {
                generateHostTcp(response.data, host_ip);
            } else {
                // Show error message
                $(chartIdStatus).html(
                    '\
                     ' + response.status + ': ' + response.data + ''
                )
            }
        }
    });
};

//------------------- Host Count of Distinct Dst Ports Chart --------------------------
// Generate a chart and set it to the given div
function generateHostDistinctPorts(data, host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = host_id + '-distinct-ports';
    var chartIdStatus = chartId + '-status';

    // Hide status element
    $('#' + chartIdStatus).hide();
    // Show chart element
    $('#' + chartId).show();

    // ZingChart configuration
    var myConfig = {
        type: 'mixed',
        backgroundColor:'#fff',
        title:{
            text: 'Distinct Destination Ports for the Host ' + host_ip,
            adjustLayout: true,
            fontColor:"#444444"
        },
        legend:{
            align: 'center',
            verticalAlign: 'top',
            backgroundColor:'none',
            borderWidth: 0,
            item:{
                fontColor:'#444444',
                cursor: 'hand'
            },
            marker:{
                type:'circle',
                borderWidth: 0,
                cursor: 'hand'
            },
            toggleAction: 'remove'
        },
        plotarea:{
            margin:'dynamic 70'
        },
        plot:{
            lineWidth: 2,
            marker:{
                borderWidth: 0,
                size: 3
            },
            "data-min": data.data_min,
            "data-max": data.data_max,
        },
        scaleX:{
            lineColor: '#444444',
            zooming: true,
            item:{
                fontColor:'#444444'
            },
            transform:{
                type: 'date',
                all: '%D %M %d
%h:%i:%s'
            },
            label:{
                text: 'Time',
                visible: false
            }
        },
        scaleY:{
            minorTicks: 1,
            lineColor: '#444444',
            decimals: 0,
            tick:{
                lineColor: '#444444'
            },
            minorTick:{
                lineColor: '#444444'
            },
            minorGuide:{
                visible: false
            },
            guide:{
                lineStyle: 'dashed'
            },
            item:{
                fontColor:'#444444'
            },
            short: true
        },
        tooltip:{
            borderWidth: 0,
            borderRadius: 3
        },
        preview:{
            adjustLayout: true,
            y: '85%',
            borderColor:'#444444',
            borderWidth: 1,
            mask:{
                backgroundColor:'#658687'
            }
        },
        crosshairX:{
              scaleLabel:{
                backgroundColor:"#7CB5EC"
              },
              plotLabel:{
                backgroundColor:"white",
                multiple:false,
                borderRadius:3,
                text: "Avg: %v Ports \nRange: %data-min - %data-max Ports"
              }
            },
        series:[
          {
	        type:"line",
	        values:data.data_avg,
	        text : "Average",
            lineWidth:1,
            shadow:false,
            lineColor:"#29a2cc",
        	tooltip:{
			  visible:false
			}

          },
    	  {
		  type:"range",
			values : data.data_min_max,
			text: "Min-max range",
			backgroundColor:"#abd1f2",
			lineColor:"#abd1f2",
			lineWidth:0,
			marker:{
			  visible:false
			},
			tooltip:{
			  visible:false
			},
			guideLabel:{
			  visible:false
			}
		}
        ]

    };

    // Render ZingChart with width based on the whole panel
    zingchart.render({
	    id: chartId,
	    data: myConfig,
	    height: $('#' + host_id + '-panels').height(),
	    width: $('#' + host_id + '-panels').width()
    });
};

// Obtain flow data for a host and generate the chart
function loadHostDistinctPorts(host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = '#' + host_id + '-distinct-ports';
    var chartIdStatus = chartId + '-status';

    // Hide chart element
    $(chartId).hide();
    // Show status element
    $(chartIdStatus).show();

    // Set loading status
    $(chartIdStatus).html(
        '\
         Loading...'
    )

    // Convert times to UTC in ISO format
    var beginning = new Date( $('#datetime-beginning').val()).toISOString();
    var end = new Date( $('#datetime-end').val()).toISOString();

    // Set data request
    var data_request = encodeURI( './get_host_distinct_ports' + '?beginning=' + beginning + '&end=' + end + '&aggregation=' + $('#aggregation').val() + '&host_ip=' + host_ip);
    // Get Elasticsearch data
    $.ajax({
        async: true,
        type: 'GET',
        url: data_request,
        success: function(raw) {
            var response = jQuery.parseJSON(raw);
            if (response.status == "Ok") {
                generateHostDistinctPorts(response.data, host_ip);
            } else {
                // Show error message
                $(chartIdStatus).html(
                    '\
                     ' + response.status + ': ' + response.data + ''
                )
            }
        }
    });
};

//------------------- Host Count of Distinct Peers Chart --------------------------
// Generate a chart and set it to the given div
function generateHostDistinctPeers(data, host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = host_id + '-distinct-peers';
    var chartIdStatus = chartId + '-status';

    // Hide status element
    $('#' + chartIdStatus).hide();
    // Show chart element
    $('#' + chartId).show();

    // ZingChart configuration
    var myConfig = {
        type: 'mixed',
        backgroundColor:'#fff',
        title:{
            text: 'Distinct Peers for the Host ' + host_ip,
            adjustLayout: true,
            fontColor:"#444444"
        },
        legend:{
            align: 'center',
            verticalAlign: 'top',
            backgroundColor:'none',
            borderWidth: 0,
            item:{
                fontColor:'#444444',
                cursor: 'hand'
            },
            marker:{
                type:'circle',
                borderWidth: 0,
                cursor: 'hand'
            },
            toggleAction: 'remove'
        },
        plotarea:{
            margin:'dynamic 70'
        },
        plot:{
            lineWidth: 2,
            marker:{
                borderWidth: 0,
                size: 3
            },
            "data-min": data.data_min,
            "data-max": data.data_max,
        },
        scaleX:{
            lineColor: '#444444',
            zooming: true,
            item:{
                fontColor:'#444444'
            },
            transform:{
                type: 'date',
                all: '%D %M %d
%h:%i:%s'
            },
            label:{
                text: 'Time',
                visible: false
            }
        },
        scaleY:{
            minorTicks: 1,
            lineColor: '#444444',
            decimals: 0,
            tick:{
                lineColor: '#444444'
            },
            minorTick:{
                lineColor: '#444444'
            },
            minorGuide:{
                visible: false
            },
            guide:{
                lineStyle: 'dashed'
            },
            item:{
                fontColor:'#444444'
            },
            short: true
        },
        tooltip:{
            borderWidth: 0,
            borderRadius: 3
        },
        preview:{
            adjustLayout: true,
            y: '85%',
            borderColor:'#444444',
            borderWidth: 1,
            mask:{
                backgroundColor:'#658687'
            }
        },
        crosshairX:{
              scaleLabel:{
                backgroundColor:"#7CB5EC"
              },
              plotLabel:{
                backgroundColor:"white",
                multiple:false,
                borderRadius:3,
                text: "Avg: %v Peers \nRange: %data-min - %data-max Peers"
              }
            },
        series:[
          {
	        type:"line",
	        values:data.data_avg,
	        text : "Average",
            lineWidth:1,
            shadow:false,
            lineColor:"#29a2cc",
        	tooltip:{
			  visible:false
			}

          },
    	  {
		  type:"range",
			values : data.data_min_max,
			text: "Min-max range",
			backgroundColor:"#abd1f2",
			lineColor:"#abd1f2",
			lineWidth:0,
			marker:{
			  visible:false
			},
			tooltip:{
			  visible:false
			},
			guideLabel:{
			  visible:false
			}
		}
        ]

    };

    // Render ZingChart with width based on the whole panel
    zingchart.render({
	    id: chartId,
	    data: myConfig,
	    height: $('#' + host_id + '-panels').height(),
	    width: $('#' + host_id + '-panels').width()
    });
};

// Obtain flow data for a host and generate the chart
function loadHostDistinctPeers(host_ip) {
    // Replace dots in host_ip to dashes and swap number to chars (necessary for zingchart)
    var host_id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Elements ID
    var chartId = '#' + host_id + '-distinct-peers';
    var chartIdStatus = chartId + '-status';

    // Hide chart element
    $(chartId).hide();
    // Show status element
    $(chartIdStatus).show();

    // Set loading status
    $(chartIdStatus).html(
        '\
         Loading...'
    )

    // Convert times to UTC in ISO format
    var beginning = new Date( $('#datetime-beginning').val()).toISOString();
    var end = new Date( $('#datetime-end').val()).toISOString();

    // Set data request
    var data_request = encodeURI( './get_host_distinct_peers' + '?beginning=' + beginning + '&end=' + end + '&aggregation=' + $('#aggregation').val() + '&host_ip=' + host_ip);
    // Get Elasticsearch data
    $.ajax({
        async: true,
        type: 'GET',
        url: data_request,
        success: function(raw) {
            var response = jQuery.parseJSON(raw);
            if (response.status == "Ok") {
                generateHostDistinctPeers(response.data, host_ip);
            } else {
                // Show error message
                $(chartIdStatus).html(
                    '\
                     ' + response.status + ': ' + response.data + ''
                )
            }
        }
    });
};

//------------------- Loading functions --------------------------
// Get chart panel template
function getPanelTemplate(host_ip) {
    // Replace dots in host_ip to dashes to allow its easy use in element ID
    var id = replaceNumbers(host_ip.replace(/\./g, '-'));

    // Define charts panel template
    var panel_template = ' \

 \
             \

 \
                Detailed statistics for ' + host_ip + ' \
                 \
                     Close \
                 \

 \
             \

 \

 \
                    Flows \

 \

 \
                    TCP Flags \

 \

 \
                    Distinct Ports \

 \

 \
                    Distinct Peers \

 \

 \
             \

 \
                 \

 \
                     \

 \
                     \

 \

 \
                 \

 \
                     \

 \
                     \

 \

 \
                 \

 \
                     \

 \
                     \

 \

 \
                 \

 \
                     \

 \
                     \

 \

 \

 \

 \
    '

    // Return generated template
    return panel_template
}

// Load defined host charts
function loadHostCharts(host_ip) {
    // Check if host is already loaded
    if (!isHostLoaded(host_ip)) {
        // Get a new panel template
        var panel_template = $.parseHTML(getPanelTemplate(host_ip));

        // Append panel to the current list
        $('#detailed-charts').append(panel_template);

        // Load all detailed charts
        loadHostFlowsChart(host_ip);
        loadHostTcpChart(host_ip);
        loadHostDistinctPorts(host_ip);
        loadHostDistinctPeers(host_ip);

        // Add host to loaded hosts to not display it again
        addLoadedHost(host_ip);

        // Scroll to the bottom of the page (to loading chart)
        window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight);
    }
};

// Load heatmap chart when the page is loaded
$(window).load(loadHeatmapChart());