From 38b24b7ef6e3d82c1a14b93c4ffafadbc2f1ae9b Mon Sep 17 00:00:00 2001
From: Josh Blum
Date: Tue, 26 Mar 2013 00:41:12 -0500
Subject: gras: rename stats to query

---
 python/gras/CMakeLists.txt                    |   2 +-
 python/gras/GRAS_HierBlock.i                  |   4 +-
 python/gras/query/CMakeLists.txt              |  26 ++++
 python/gras/query/__init__.py                 |  52 +++++++
 python/gras/query/chart_factory.js            | 209 ++++++++++++++++++++++++++
 python/gras/query/chart_handler_breakdown.js  |  37 +++++
 python/gras/query/chart_overall_throughput.js |  46 ++++++
 python/gras/query/chart_overhead_compare.js   |  37 +++++
 python/gras/query/chart_total_io_counts.js    |  62 ++++++++
 python/gras/query/main.css                    | 161 ++++++++++++++++++++
 python/gras/query/main.html                   |  49 ++++++
 python/gras/query/main.js                     |  76 ++++++++++
 python/gras/query/utils.js                    |  84 +++++++++++
 python/gras/stats/CMakeLists.txt              |  26 ----
 python/gras/stats/__init__.py                 |  52 -------
 python/gras/stats/chart_factory.js            | 209 --------------------------
 python/gras/stats/chart_handler_breakdown.js  |  37 -----
 python/gras/stats/chart_overall_throughput.js |  46 ------
 python/gras/stats/chart_overhead_compare.js   |  37 -----
 python/gras/stats/chart_total_io_counts.js    |  62 --------
 python/gras/stats/main.css                    | 161 --------------------
 python/gras/stats/main.html                   |  49 ------
 python/gras/stats/main.js                     |  76 ----------
 python/gras/stats/utils.js                    |  84 -----------
 24 files changed, 842 insertions(+), 842 deletions(-)
 create mode 100644 python/gras/query/CMakeLists.txt
 create mode 100644 python/gras/query/__init__.py
 create mode 100644 python/gras/query/chart_factory.js
 create mode 100644 python/gras/query/chart_handler_breakdown.js
 create mode 100644 python/gras/query/chart_overall_throughput.js
 create mode 100644 python/gras/query/chart_overhead_compare.js
 create mode 100644 python/gras/query/chart_total_io_counts.js
 create mode 100644 python/gras/query/main.css
 create mode 100644 python/gras/query/main.html
 create mode 100644 python/gras/query/main.js
 create mode 100644 python/gras/query/utils.js
 delete mode 100644 python/gras/stats/CMakeLists.txt
 delete mode 100644 python/gras/stats/__init__.py
 delete mode 100644 python/gras/stats/chart_factory.js
 delete mode 100644 python/gras/stats/chart_handler_breakdown.js
 delete mode 100644 python/gras/stats/chart_overall_throughput.js
 delete mode 100644 python/gras/stats/chart_overhead_compare.js
 delete mode 100644 python/gras/stats/chart_total_io_counts.js
 delete mode 100644 python/gras/stats/main.css
 delete mode 100644 python/gras/stats/main.html
 delete mode 100644 python/gras/stats/main.js
 delete mode 100644 python/gras/stats/utils.js

(limited to 'python/gras')

diff --git a/python/gras/CMakeLists.txt b/python/gras/CMakeLists.txt
index f3ef329..e91d8df 100644
--- a/python/gras/CMakeLists.txt
+++ b/python/gras/CMakeLists.txt
@@ -1,7 +1,7 @@
 ########################################################################
 # add subdirs
 ########################################################################
-add_subdirectory(stats)
+add_subdirectory(query)
 
 ########################################################################
 # Include swig generation macros
diff --git a/python/gras/GRAS_HierBlock.i b/python/gras/GRAS_HierBlock.i
index 32c823b..12a5952 100644
--- a/python/gras/GRAS_HierBlock.i
+++ b/python/gras/GRAS_HierBlock.i
@@ -75,10 +75,10 @@ struct TopBlockPython : TopBlock
         return TopBlock::wait(timeout);
     }
 
-    std::string get_stats(const std::string &args)
+    std::string query(const std::string &args)
     {
         PyTSPhondler phil;
-        return TopBlock::get_stats(args);
+        return TopBlock::query(args);
     }
 };
 
diff --git a/python/gras/query/CMakeLists.txt b/python/gras/query/CMakeLists.txt
new file mode 100644
index 0000000..ab49532
--- /dev/null
+++ b/python/gras/query/CMakeLists.txt
@@ -0,0 +1,26 @@
+########################################################################
+# Install rules
+########################################################################
+include(GrPython)
+
+GR_PYTHON_INSTALL(
+    FILES
+    __init__.py
+    DESTINATION ${GR_PYTHON_DIR}/gras/query
+    COMPONENT ${GRAS_COMP_PYTHON}
+)
+
+INSTALL(
+    FILES
+    main.html
+    main.js
+    utils.js
+    chart_factory.js
+    chart_overhead_compare.js
+    chart_overall_throughput.js
+    chart_handler_breakdown.js
+    chart_total_io_counts.js
+    main.css
+    DESTINATION ${GR_PYTHON_DIR}/gras/query
+    COMPONENT ${GRAS_COMP_PYTHON}
+)
diff --git a/python/gras/query/__init__.py b/python/gras/query/__init__.py
new file mode 100644
index 0000000..5789fab
--- /dev/null
+++ b/python/gras/query/__init__.py
@@ -0,0 +1,52 @@
+import time
+import BaseHTTPServer
+
+import os
+__path__ = os.path.abspath(os.path.dirname(__file__))
+
+server_registry = dict()
+
+class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+
+    def do_HEAD(s):
+        s.send_response(200)
+        s.send_header("Content-type", "text/html")
+        s.end_headers()
+
+    def do_GET(s):
+        """Respond to a GET request."""
+        if s.path.endswith('.xml'):
+            s.send_response(200)
+            s.send_header("Content-type", "text/xml")
+            s.end_headers()
+            s.wfile.write(server_registry[s.server]['top_block'].query(s.path))
+            return
+        path = s.path
+        if path.startswith('/'): path = path[1:]
+        if not path: path = 'main.html'
+        target = os.path.join(__path__, path)
+        if os.path.exists(target):
+            s.send_response(200)
+            if target.endswith('.js'): s.send_header("Content-type", "text/javascript")
+            elif target.endswith('.css'): s.send_header("Content-type", "text/css")
+            else: s.send_header("Content-type", "text")
+            s.end_headers()
+            s.wfile.write(open(target).read())
+        else:
+            s.send_response(404)
+            s.send_header("Content-type", "text/html")
+            s.end_headers()
+            s.wfile.write("<p>not found</p>")
+
+import select
+
+class http_server(object):
+    def __init__(self, args, **kwargs):
+        server_class = BaseHTTPServer.HTTPServer
+        self._httpd = server_class(args, MyHandler)
+        server_registry[self._httpd] = kwargs
+
+    def serve_forever(self):
+        while True:
+            try: self._httpd.serve_forever()
+            except select.error: pass
diff --git a/python/gras/query/chart_factory.js b/python/gras/query/chart_factory.js
new file mode 100644
index 0000000..3d2b0bc
--- /dev/null
+++ b/python/gras/query/chart_factory.js
@@ -0,0 +1,209 @@
+/***********************************************************************
+ * Chart registry for now chart types
+ **********************************************************************/
+var gras_chart_get_registry = function()
+{
+    return [
+        {key:'overhead_compare', name:'Overhead Compare', factory:GrasChartOverheadCompare},
+        {key:'overall_throughput', name:'Overall Throughput', factory:GrasChartOverallThroughput},
+        {key:'handler_breakdown', name:'Handler Breakdown', factory:GrasChartHandlerBreakdown},
+        {key:'total_io_counts', name:'I/O port Totals', factory:GrasChartTotalIoCounts},
+    ];
+}
+
+/***********************************************************************
+ * One time setup
+ **********************************************************************/
+function gras_chart_factory_setup(registry, point)
+{
+    var id = $('gras_stats:first', point).attr('id');
+    registry.top_id = id;
+    $('#top_name').append(' - ' + id);
+    $('block', point).each(function(index, block)
+    {
+        var id = $(block).attr('id');
+        registry.block_ids.push(id);
+        var container = $('#chart_designer_blocks');
+        var div = $('<div />');
+        $(div).append('<label>' + id + '</label>');
+        var input = $('<input />').attr({
+            type: 'checkbox',
+            name: id
+        });
+        input.attr('checked', false);
+        $(div).append(input);
+        $(container).append(div);
+    });
+}
+
+/***********************************************************************
+ * chart factory input handler
+ **********************************************************************/
+function gras_chart_factory_handle_input(registry)
+{
+    //get a list of the selected blocks
+    var selected_blocks = new Array();
+    $.each($('#chart_designer_blocks input'), function(index, input)
+    {
+        var input = $(input);
+        if (input.is(':checked'))
+        {
+            selected_blocks.push(input.attr('name'));
+        }
+    });
+
+    //get the type of chart to create
+    var chart_type = $('#chart_type_selector').val();
+
+    //create args for the factory make
+    var args = {
+        block_ids:selected_blocks,
+        chart_type:chart_type,
+    };
+
+    //call into the factory with args
+    gras_chart_factory_make(registry, args);
+}
+
+/***********************************************************************
+ * save/load to/from local storage
+ **********************************************************************/
+function gras_chart_save(registry)
+{
+    if (typeof(Storage) === "undefined") return;
+    var all_args = new Array();
+    $.each(registry.active_charts, function(index, info)
+    {
+        all_args.push(info.args);
+    });
+    localStorage.setItem(registry.top_id, JSON.stringify(all_args));
+}
+
+function gras_chart_load(registry)
+{
+    if (typeof(Storage) === "undefined") return;
+    var chart_args = JSON.parse(localStorage.getItem(registry.top_id));
+    if (!chart_args) return;
+    $.each(chart_args, function(args_i, args)
+    {
+        //check that the blocks saved in the args actually exist
+        var do_make = true;
+        $.each(args.block_ids, function(block_id_i, block_id)
+        {
+            if ($.inArray(block_id, registry.block_ids) < 0)
+            {
+                do_make = false;
+            }
+        });
+        if (do_make) gras_chart_factory_make(registry, args);
+    });
+}
+
+/***********************************************************************
+ * chart factory make routine
+ **********************************************************************/
+function gras_chart_factory_make(registry, args)
+{
+    //create containers
+    var chart_box = $('<table />').attr({class:'chart_container'});
+    var tr = $('<tr />');
+    var td = $('<td />');
+    tr.append(td);
+
+    //call into the factory
+    args.panel = td.get(0);
+    try
+    {
+        var chart = new registry.chart_factories[args.chart_type](args);
+    }
+    catch(err)
+    {
+        return;
+    }
+
+    //setup the title
+    var tr_title = $('<tr />');
+    var th_title = $('<th />');
+    tr_title.append(th_title);
+    th_title.text(chart.title);
+
+    //register the chart
+    var chart_info = {chart:chart,args:args};
+    registry.active_charts.push(chart_info);
+    $('#charts_panel').append(chart_box);
+
+    //close button
+    var close_div = $('<div/>').attr({class:'chart_designer_block_close'});
+    var close_href = $('<a />').attr({href:'#', class:"ui-dialog-titlebar-close ui-corner-all", role:"button"});
+    var close_span = $('<span />').attr({class:"ui-icon ui-icon-closethick"}).text('close');
+    close_div.append(close_href);
+    close_href.append(close_span);
+    th_title.append(close_div);
+    $(close_href).click(function()
+    {
+        var index = $.inArray(chart_info, registry.active_charts);
+        registry.active_charts.splice(index, 1);
+        chart_box.remove();
+        gras_chart_save(registry);
+    });
+    gras_chart_save(registry);
+
+    //finish gui building
+    chart_box.append(tr_title);
+    chart_box.append(tr);
+}
+
+/***********************************************************************
+ * chart factory handle online/offline
+ **********************************************************************/
+function gras_chart_factory_online(registry)
+{
+    if (!registry.online) registry.offline_count++;
+    if (registry.online) $('#page').css('background-color', '#EEEEFF');
+    else if (registry.offline_count%2 == 0) $('#page').css('background-color', '#FF4848');
+    else if (registry.offline_count%2 == 1) $('#page').css('background-color', '#EEEEFF');
+}
+
+/***********************************************************************
+ * chart factory init
+ **********************************************************************/
+function gras_chart_factory_init(registry)
+{
+    //init registry containers
+    registry.active_charts = new Array();
+    registry.chart_factories = new Array();
+
+    //install callback for chart factory
+    $('#chart_factory_button').click(function()
+    {
+        gras_chart_factory_handle_input(registry);
+    });
+
+    //init the chart selection input
+    $.each(gras_chart_get_registry(), function(index, options)
+    {
+        registry.chart_factories[options.key] = options.factory;
+        var option = $('<option />').attr({value: options.key});
+        option.text(options.name);
+        $('#chart_type_selector').append(option);
+    });
+
+    //init overall config gui element for rate
+    var overall_rate = $('#chart_update_rate');
+    overall_rate.val(registry.overall_rate);
+    overall_rate.change(function()
+    {
+        registry.overall_rate = overall_rate.val();
+    });
+
+    //init overall config gui element for activity
+    registry.overall_active = true;
+    var overall_active = $('#chart_active_state');
+    overall_active.attr('checked', registry.overall_active);
+    overall_active.change(function()
+    {
+        registry.overall_active = overall_active.is(':checked');
+        if (registry.overall_active) gras_query_stats(registry);
+        else window.clearInterval(registry.timeout_handle);
+    });
+}
diff --git a/python/gras/query/chart_handler_breakdown.js b/python/gras/query/chart_handler_breakdown.js
new file mode 100644
index 0000000..8e90fc3
--- /dev/null
+++ b/python/gras/query/chart_handler_breakdown.js
@@ -0,0 +1,37 @@
+function GrasChartHandlerBreakdown(args)
+{
+    //input checking
+    if (args.block_ids.length != 1) throw gras_error_dialog(
+        "GrasChartHandlerBreakdown",
+        "Error making handler breakdown chart.\n"+
+        "Specify only one block for this chart."
+    );
+
+    //save enable
+    this.block_id = args.block_ids[0];
+
+    //make new chart
+    this.chart = new google.visualization.PieChart(args.panel);
+
+    this.title = "Handler Breakdown - " + this.block_id;
+}
+
+GrasChartHandlerBreakdown.prototype.update = function(point)
+{
+    var percents = gras_extract_percent_times(point, this.block_id);
+    var data = google.visualization.arrayToDataTable([
+          ['Task', 'Percent'],
+          ['Work prep', percents['prep']],
+          ['Work task', percents['work']],
+          ['Work post', percents['post']],
+          ['Input tasks', percents['input']],
+          ['Output tasks', percents['output']],
+    ]);
+
+    var options = {
+        width:GRAS_CHARTS_STD_WIDTH,
+        chartArea:{left:5,top:0,right:5,bottom:0,width:"100%",height:"100%"},
+    };
+
+    this.chart.draw(data, options);
+};
diff --git a/python/gras/query/chart_overall_throughput.js b/python/gras/query/chart_overall_throughput.js
new file mode 100644
index 0000000..4947479
--- /dev/null
+++ b/python/gras/query/chart_overall_throughput.js
@@ -0,0 +1,46 @@
+function GrasChartOverallThroughput(args)
+{
+    //save enables
+    this.ids = args.block_ids;
+
+    //input checking
+    if (this.ids.length == 0) throw gras_error_dialog(
+        "GrasChartOverallThroughput",
+        "Error making overall thoughput chart.\n"+
+        "Specify at least 1 block for this chart."
+    );
+
+    //make new chart
+    this.chart = new google.visualization.LineChart(args.panel);
+
+    this.title = "Overall Throughput vs Time";
+    this.history = new Array();
+}
+
+GrasChartOverallThroughput.prototype.update = function(point)
+{
+    this.history.push(point);
+    if (this.history.length == 1) this.p0 = point;
+    if (this.history.length < 2) return;
+    if (this.history.length > 10) this.history.splice(0, 1);
+
+    var data_set = [['Throughput'].concat(this.ids)];
+    for (var i = 1; i < this.history.length; i++)
+    {
+        var row = new Array();
+        row.push(gras_extract_stat_time_delta(this.p0, this.history[i]).toFixed(2).toString());
+        for (var j = 0; j < this.ids.length; j++)
+        {
+            row.push(gras_extract_throughput_delta(this.history[i-1], this.history[i], this.ids[j])/1e6);
+        }
+        data_set.push(row);
+    }
+
+    var chart_data = google.visualization.arrayToDataTable(data_set);
+    var options = {
+        width:GRAS_CHARTS_STD_WIDTH*2,
+        chartArea:{left:0,top:0,right:0,bottom:0,width:"100%",height:"85%"},
+        legend: {'position': 'bottom'},
+    };
+    this.chart.draw(chart_data, options);
+};
diff --git a/python/gras/query/chart_overhead_compare.js b/python/gras/query/chart_overhead_compare.js
new file mode 100644
index 0000000..c373142
--- /dev/null
+++ b/python/gras/query/chart_overhead_compare.js
@@ -0,0 +1,37 @@
+function GrasChartOverheadCompare(args)
+{
+    //save enables
+    this.ids = args.block_ids;
+
+    //input checking
+    if (this.ids.length <= 1) throw gras_error_dialog(
+        "GrasChartOverheadCompare",
+        "Error making overhead compare chart.\n"+
+        "Specify at least 2 blocks for this chart."
+    );
+
+    //make new chart
+    this.chart = new google.visualization.PieChart(args.panel);
+
+    this.title = "Overhead Comparison";
+}
+
+GrasChartOverheadCompare.prototype.update = function(point)
+{
+    var data_set = new Array();
+    data_set.push(['Task', 'Percent']);
+    $.each(this.ids, function(index, id)
+    {
+        var percents = gras_extract_percent_times(point, id);
+        data_set.push([id, percents['total']]);
+    });
+
+    var data = google.visualization.arrayToDataTable(data_set)
+
+    var options = {
+        width:GRAS_CHARTS_STD_WIDTH,
+        chartArea:{left:5,top:0,right:5,bottom:0,width:"100%",height:"100%"},
+    };
+
+    this.chart.draw(data, options);
+};
diff --git a/python/gras/query/chart_total_io_counts.js b/python/gras/query/chart_total_io_counts.js
new file mode 100644
index 0000000..5aaaf24
--- /dev/null
+++ b/python/gras/query/chart_total_io_counts.js
@@ -0,0 +1,62 @@
+function GrasChartTotalIoCounts(args)
+{
+    //input checking
+    if (args.block_ids.length != 1) throw gras_error_dialog(
+        "GrasChartTotalIoCounts",
+        "Error making total IO counts chart.\n"+
+        "Specify only one block for this chart."
+    );
+
+    //settings
+    this.block_id = args.block_ids[0];
+    this.div = $('<div />').attr({class:'chart_total_io_counts'});
+    $(args.panel).append(this.div);
+    this.title = "I/O Totals - " + this.block_id;
+}
+
+GrasChartTotalIoCounts.prototype.update = function(point)
+{
+    var block_data = $('block[id="' + this.block_id + '"]', point);
+    var ul = $('<ul />');
+    $('ul', this.div).remove(); //clear old lists
+    this.div.append(ul);
+
+    {
+        var init_time = parseInt($('init_time', block_data).text());
+        var stats_time = parseInt($('stats_time', block_data).text());
+        var tps = parseInt($('tps', block_data).text());
+        var duration = (stats_time - init_time)/tps;
+        var li = $('<li />');
+        var strong = $('<strong />').text('Elapsed' + ': ');
+        var span = $('<span />').text(duration.toFixed(2).toString() + ' secs');
+        li.append(strong);
+        li.append(span);
+        ul.append(li);
+    }
+
+    var stuff = [
+        ['Input', 'items', 'items_consumed'],
+        ['Input', 'tags', 'tags_consumed'],
+        ['Input', 'msgs', 'msgs_consumed'],
+        ['Output', 'items', 'items_produced'],
+        ['Output', 'tags', 'tags_produced'],
+        ['Output', 'msgs', 'msgs_produced'],
+    ];
+
+    $.each(stuff, function(contents_i, contents)
+    {
+        var dir = contents[0];
+        var units = contents[1];
+        var key = contents[2];
+        $(key, block_data).each(function(index, elem)
+        {
+            var count = parseInt($(elem).text());
+            var li = $('<li />');
+            var strong = $('<strong />').text(dir + index.toString() + ': ');
+            var span = $('<span />').text(count.toString() + ' ' + units);
+            li.append(strong);
+            li.append(span);
+            if (count > 0) ul.append(li);
+        });
+    });
+}
diff --git a/python/gras/query/main.css b/python/gras/query/main.css
new file mode 100644
index 0000000..b5f62f1
--- /dev/null
+++ b/python/gras/query/main.css
@@ -0,0 +1,161 @@
+*{
+margin:0px;
+padding:0px;
+}
+
+body{
+font-family:Arial, Helvetica, sans-serif;
+font-size:9pt;
+color:black;
+background-color:white;
+}
+
+.chart_designer_block_close
+{
+float:right;
+}
+
+#chart_designer_blocks div
+{
+float:left;
+}
+
+#chart_designer_blocks label
+{
+text-decoration:underline;
+}
+
+#chart_designer_blocks input
+{
+margin-right:10px;
+margin-left:2px;
+}
+
+.chart_total_io_counts li
+{
+list-style-type:none;
+text-align: left;
+padding: 0px;
+margin: 0px;
+font-size:90%;
+}
+
+.chart_container
+{
+float:left;
+}
+
+#page{
+padding:10px;
+color:inherit;
+background-color:inherit;
+}
+
+#page h1{
+font-size:130%;
+border-left:1px solid #333333;
+border-bottom:1px solid #333333;
+text-align:left;
+padding:10px 0px 10px 10px;
+margin:10px 5px 20px 5px;
+color:#333333;
+background-color:inherit;
+}
+
+#page h2{
+font-size:130%;
+text-align:center;
+padding:20px 0px 10px 0px;
+color:#333333;
+background-color:inherit;
+}
+
+#page h3{
+font-size:110%;
+text-align:left;
+padding:15px 0px 5px 10px;
+text-decoration:underline;
+color:#333333;
+background-color:inherit;
+}
+
+#page h4{
+font-size:105%;
+text-align:center;
+padding:5px 0px 3px 0px;
+text-decoration:underline;
+}
+
+#page p{
+text-indent:20px;
+padding:5px 0px 5px 10px;
+}
+
+#page strong{
+}
+
+#page em{
+}
+
+#page li{
+padding:5px 5px 0px 3px;
+}
+
+#page ul, #page ol{
+padding:5px 0px 5px 40px;
+}
+
+#page img{
+margin:10px auto 10px auto;
+display:block;
+border-style:none;
+}
+
+#page a:link, #page a:visited{
+color:#236B8E;
+background-color:inherit;
+text-decoration:none;
+}
+
+#page a:hover{
+color:#4985D6;
+background-color:inherit;
+text-decoration:none;
+}
+
+#page pre{
+border:1px inset #333333;
+padding:5px;
+margin:10px 5px 10px 5px;
+color:inherit;
+background-color:#FCFCFC;
+font-size:90%;
+}
+
+#page hr{
+margin:10px 0px 0px 0px;
+}
+
+#page table{
+padding:5px;
+}
+
+#page th{
+padding:3px;
+border:1px solid #333333;
+text-align:center;
+color:inherit;
+background-color:#ECECEC;
+}
+
+#page tr{
+}
+
+#page td{
+padding:3px;
+border:1px solid #333333;
+text-align:center;
+color:inherit;
+background-color:#FCFCFC;
+}
+
diff --git a/python/gras/query/main.html b/python/gras/query/main.html
new file mode 100644
index 0000000..eeb221d
--- /dev/null
+++ b/python/gras/query/main.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
+    <meta http-equiv="Content-Style-Type" content="text/css" />
+    <title>GRAS Status Monitor</title>
+    <link rel="stylesheet" type="text/css" href="/main.css" />
+    <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
+    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
+    <script type="text/javascript" src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
+    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
+    <script type="text/javascript" src="/utils.js"></script>
+    <script type="text/javascript" src="/chart_factory.js"></script>
+    <script type="text/javascript" src="/chart_overhead_compare.js"></script>
+    <script type="text/javascript" src="/chart_overall_throughput.js"></script>
+    <script type="text/javascript" src="/chart_handler_breakdown.js"></script>
+    <script type="text/javascript" src="/chart_total_io_counts.js"></script>
+    <script type="text/javascript" src="/main.js"></script>
+    <script type="text/javascript">
+        google.load('visualization', '1.0', {'packages':['corechart']});
+        google.setOnLoadCallback(gras_stats_main);
+    </script>
+</head>
+
+<body id='page'>
+    <div id="chart_designer">
+        <table>
+            <tr>
+                <th id="top_name">Blocks Available</th>
+                <th>Chart Types</th>
+                <th>Global Options</th>
+            </tr>
+            <tr>
+                <td id="chart_designer_blocks" rowspan='2'></td>
+                <td><select id="chart_type_selector" /></td>
+                <td><label>Updates/sec:</label><input id="chart_update_rate" type="number" name="rate" min="1" max="10" size="4" /></td>
+            </tr>
+            <tr>
+                <td><input type="submit" value="Create New Chart" id="chart_factory_button" /></td>
+                <td><label>Active?</label><input id="chart_active_state" type="checkbox" name="active" /></td>
+            </tr>
+        </table>
+    </div>
+    <div id="charts_panel"></div>
+    <div style="display:none" id="div-dialog-warning">
+    </div>
+</body>
+
+</html>
diff --git a/python/gras/query/main.js b/python/gras/query/main.js
new file mode 100644
index 0000000..a27c0b7
--- /dev/null
+++ b/python/gras/query/main.js
@@ -0,0 +1,76 @@
+/***********************************************************************
+ * Some constants
+ **********************************************************************/
+var GRAS_CHARTS_STD_WIDTH = 250;
+
+/***********************************************************************
+ * Stats registry data structure
+ **********************************************************************/
+var GrasStatsRegistry = function()
+{
+    this.init = false;
+    this.overall_rate = 2.0;
+    this.overall_active = true;
+    this.block_ids = new Array();
+    this.top_id = 'top';
+    this.online = true;
+    this.offline_count = 0;
+}
+
+/***********************************************************************
+ * Query stats
+ **********************************************************************/
+var gras_query_stats = function(registry)
+{
+    $.ajax({
+        type: "GET",
+        async: true,
+        url: "/stats.xml",
+        dataType: "xml",
+        success: function(xml)
+        {
+            registry.online = true;
+            gras_chart_factory_online(registry);
+            if (registry.overall_active)
+            {
+                if ($(xml, "gras_stats") !== undefined)
+                {
+                    if (!registry.init)
+                    {
+                        gras_chart_factory_setup(registry, xml);
+                        try{gras_chart_load(registry);}catch(e){}
+                        registry.init = true;
+                    }
+                    $.each(registry.active_charts, function(index, chart_info)
+                    {
+                        chart_info.chart.update(xml);
+                    });
+                }
+
+                registry.timeout_handle = window.setTimeout(function()
+                {
+                    gras_query_stats(registry);
+                }, Math.round(1000/registry.overall_rate));
+            }
+        },
+        error: function()
+        {
+            registry.online = false;
+            gras_chart_factory_online(registry);
+            registry.timeout_handle = window.setTimeout(function()
+            {
+                gras_query_stats(registry);
+            }, 1000);
+        },
+    });
+}
+
+/***********************************************************************
+ * Init
+ **********************************************************************/
+var gras_stats_main = function()
+{
+    var registry = new GrasStatsRegistry();
+    gras_chart_factory_init(registry);
+    gras_query_stats(registry);
+}
diff --git a/python/gras/query/utils.js b/python/gras/query/utils.js
new file mode 100644
index 0000000..f5e5ee8
--- /dev/null
+++ b/python/gras/query/utils.js
@@ -0,0 +1,84 @@
+/***********************************************************************
+ * Utility functions for stats
+ **********************************************************************/
+var gras_extract_total_items = function(point, id)
+{
+    var block_data = $('block[id="' + id + '"]', point);
+    var total_items = 0;
+    $('items_consumed,items_produced', block_data).each(function()
+    {
+        total_items += parseInt($(this).text());
+    });
+    return total_items;
+}
+
+var gras_extract_throughput_delta = function(p0, p1, id)
+{
+    var d0 = $('block[id="' + id + '"]', p0);
+    var d1 = $('block[id="' + id + '"]', p1);
+    var t0 = parseInt($('stats_time', d0).text());
+    var t1 = parseInt($('stats_time', d1).text());
+    var tps = parseInt($('tps', d0).text());
+    var items0 = gras_extract_total_items(p0, id);
+    var items1 = gras_extract_total_items(p1, id);
+    return ((items1-items0)*tps)/(t1-t0);
+}
+
+var gras_extract_throughput = function(point, id)
+{
+    var block_data = $('block[id="' + id + '"]', point);
+    var start_time = parseInt($('start_time', block_data).text());
+    var stats_time = parseInt($('stats_time', block_data).text());
+    var tps = parseInt($('tps', block_data).text());
+    var total_items = gras_extract_total_items(point, id);
+    return (total_items*tps)/(stats_time-start_time);
+}
+
+var gras_extract_stat_time_delta = function(p0, p1)
+{
+    var t0 = parseInt($('now', p0).text());
+    var t1 = parseInt($('now', p1).text());
+    var tps = parseInt($('tps', p0).first().text());
+    return (t1-t0)/(tps);
+}
+
+var gras_extract_percent_times = function(point, id)
+{
+    var block_data = $('block[id="' + id + '"]', point);
+    var data = {
+        prep: parseInt($('total_time_prep', block_data).text()),
+        work: parseInt($('total_time_work', block_data).text()),
+        post: parseInt($('total_time_post', block_data).text()),
+        input: parseInt($('total_time_input', block_data).text()),
+        output: parseInt($('total_time_output', block_data).text()),
+    };
+    var total = 0;
+    $.each(data, function(key, val)
+    {
+        total += val;
+    });
+    data['total'] = total;
+    return data;
+}
+
+var gras_animate_show_hide = function(elem, show)
+{
+    if (show) elem.slideDown("fast");
+    else elem.slideUp("fast");
+}
+
+var gras_error_dialog = function(error_title, error_text)
+{
+    $("#div-dialog-warning").text(error_text);
+    $("#div-dialog-warning").dialog({
+        title: error_title,
+        resizable: false,
+        height: 160,
+        modal: true,
+        buttons: {
+            "Ok" : function () {
+                $(this).dialog("close");
+            }
+        }
+    }).parent().addClass("ui-state-error");
+}
diff --git a/python/gras/stats/CMakeLists.txt b/python/gras/stats/CMakeLists.txt
deleted file mode 100644
index 54502a5..0000000
--- a/python/gras/stats/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-########################################################################
-# Install rules
-########################################################################
-include(GrPython)
-
-GR_PYTHON_INSTALL(
-    FILES
-    __init__.py
-    DESTINATION ${GR_PYTHON_DIR}/gras/stats
-    COMPONENT ${GRAS_COMP_PYTHON}
-)
-
-INSTALL(
-    FILES
-    main.html
-    main.js
-    utils.js
-    chart_factory.js
-    chart_overhead_compare.js
-    chart_overall_throughput.js
-    chart_handler_breakdown.js
-    chart_total_io_counts.js
-    main.css
-    DESTINATION ${GR_PYTHON_DIR}/gras/stats
-    COMPONENT ${GRAS_COMP_PYTHON}
-)
diff --git a/python/gras/stats/__init__.py b/python/gras/stats/__init__.py
deleted file mode 100644
index 330abd4..0000000
--- a/python/gras/stats/__init__.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import time
-import BaseHTTPServer
-
-import os
-__path__ = os.path.abspath(os.path.dirname(__file__))
-
-server_registry = dict()
-
-class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
-
-    def do_HEAD(s):
-        s.send_response(200)
-        s.send_header("Content-type", "text/html")
-        s.end_headers()
-
-    def do_GET(s):
-        """Respond to a GET request."""
-        if s.path.endswith('stats.xml'):
-            s.send_response(200)
-            s.send_header("Content-type", "text/xml")
-            s.end_headers()
-            s.wfile.write(server_registry[s.server].get_stats(""))
-            return
-        path = s.path
-        if path.startswith('/'): path = path[1:]
-        if not path: path = 'main.html'
-        target = os.path.join(__path__, path)
-        if os.path.exists(target):
-            s.send_response(200)
-            if target.endswith('.js'): s.send_header("Content-type", "text/javascript")
-            elif target.endswith('.css'): s.send_header("Content-type", "text/css")
-            else: s.send_header("Content-type", "text")
-            s.end_headers()
-            s.wfile.write(open(target).read())
-        else:
-            s.send_response(404)
-            s.send_header("Content-type", "text/html")
-            s.end_headers()
-            s.wfile.write("<p>not found</p>")
-
-import select
-
-class http_server(object):
-    def __init__(self, args, top_block):
-        server_class = BaseHTTPServer.HTTPServer
-        self._httpd = server_class(args, MyHandler)
-        server_registry[self._httpd] = top_block
-
-    def serve_forever(self):
-        while True:
-            try: self._httpd.serve_forever()
-            except select.error: pass
diff --git a/python/gras/stats/chart_factory.js b/python/gras/stats/chart_factory.js
deleted file mode 100644
index 3d2b0bc..0000000
--- a/python/gras/stats/chart_factory.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/***********************************************************************
- * Chart registry for now chart types
- **********************************************************************/
-var gras_chart_get_registry = function()
-{
-    return [
-        {key:'overhead_compare', name:'Overhead Compare', factory:GrasChartOverheadCompare},
-        {key:'overall_throughput', name:'Overall Throughput', factory:GrasChartOverallThroughput},
-        {key:'handler_breakdown', name:'Handler Breakdown', factory:GrasChartHandlerBreakdown},
-        {key:'total_io_counts', name:'I/O port Totals', factory:GrasChartTotalIoCounts},
-    ];
-}
-
-/***********************************************************************
- * One time setup
- **********************************************************************/
-function gras_chart_factory_setup(registry, point)
-{
-    var id = $('gras_stats:first', point).attr('id');
-    registry.top_id = id;
-    $('#top_name').append(' - ' + id);
-    $('block', point).each(function(index, block)
-    {
-        var id = $(block).attr('id');
-        registry.block_ids.push(id);
-        var container = $('#chart_designer_blocks');
-        var div = $('<div />');
-        $(div).append('<label>' + id + '</label>');
-        var input = $('<input />').attr({
-            type: 'checkbox',
-            name: id
-        });
-        input.attr('checked', false);
-        $(div).append(input);
-        $(container).append(div);
-    });
-}
-
-/***********************************************************************
- * chart factory input handler
- **********************************************************************/
-function gras_chart_factory_handle_input(registry)
-{
-    //get a list of the selected blocks
-    var selected_blocks = new Array();
-    $.each($('#chart_designer_blocks input'), function(index, input)
-    {
-        var input = $(input);
-        if (input.is(':checked'))
-        {
-            selected_blocks.push(input.attr('name'));
-        }
-    });
-
-    //get the type of chart to create
-    var chart_type = $('#chart_type_selector').val();
-
-    //create args for the factory make
-    var args = {
-        block_ids:selected_blocks,
-        chart_type:chart_type,
-    };
-
-    //call into the factory with args
-    gras_chart_factory_make(registry, args);
-}
-
-/***********************************************************************
- * save/load to/from local storage
- **********************************************************************/
-function gras_chart_save(registry)
-{
-    if (typeof(Storage) === "undefined") return;
-    var all_args = new Array();
-    $.each(registry.active_charts, function(index, info)
-    {
-        all_args.push(info.args);
-    });
-    localStorage.setItem(registry.top_id, JSON.stringify(all_args));
-}
-
-function gras_chart_load(registry)
-{
-    if (typeof(Storage) === "undefined") return;
-    var chart_args = JSON.parse(localStorage.getItem(registry.top_id));
-    if (!chart_args) return;
-    $.each(chart_args, function(args_i, args)
-    {
-        //check that the blocks saved in the args actually exist
-        var do_make = true;
-        $.each(args.block_ids, function(block_id_i, block_id)
-        {
-            if ($.inArray(block_id, registry.block_ids) < 0)
-            {
-                do_make = false;
-            }
-        });
-        if (do_make) gras_chart_factory_make(registry, args);
-    });
-}
-
-/***********************************************************************
- * chart factory make routine
- **********************************************************************/
-function gras_chart_factory_make(registry, args)
-{
-    //create containers
-    var chart_box = $('<table />').attr({class:'chart_container'});
-    var tr = $('<tr />');
-    var td = $('<td />');
-    tr.append(td);
-
-    //call into the factory
-    args.panel = td.get(0);
-    try
-    {
-        var chart = new registry.chart_factories[args.chart_type](args);
-    }
-    catch(err)
-    {
-        return;
-    }
-
-    //setup the title
-    var tr_title = $('<tr />');
-    var th_title = $('<th />');
-    tr_title.append(th_title);
-    th_title.text(chart.title);
-
-    //register the chart
-    var chart_info = {chart:chart,args:args};
-    registry.active_charts.push(chart_info);
-    $('#charts_panel').append(chart_box);
-
-    //close button
-    var close_div = $('<div/>').attr({class:'chart_designer_block_close'});
-    var close_href = $('<a />').attr({href:'#', class:"ui-dialog-titlebar-close ui-corner-all", role:"button"});
-    var close_span = $('<span />').attr({class:"ui-icon ui-icon-closethick"}).text('close');
-    close_div.append(close_href);
-    close_href.append(close_span);
-    th_title.append(close_div);
-    $(close_href).click(function()
-    {
-        var index = $.inArray(chart_info, registry.active_charts);
-        registry.active_charts.splice(index, 1);
-        chart_box.remove();
-        gras_chart_save(registry);
-    });
-    gras_chart_save(registry);
-
-    //finish gui building
-    chart_box.append(tr_title);
-    chart_box.append(tr);
-}
-
-/***********************************************************************
- * chart factory handle online/offline
- **********************************************************************/
-function gras_chart_factory_online(registry)
-{
-    if (!registry.online) registry.offline_count++;
-    if (registry.online) $('#page').css('background-color', '#EEEEFF');
-    else if (registry.offline_count%2 == 0) $('#page').css('background-color', '#FF4848');
-    else if (registry.offline_count%2 == 1) $('#page').css('background-color', '#EEEEFF');
-}
-
-/***********************************************************************
- * chart factory init
- **********************************************************************/
-function gras_chart_factory_init(registry)
-{
-    //init registry containers
-    registry.active_charts = new Array();
-    registry.chart_factories = new Array();
-
-    //install callback for chart factory
-    $('#chart_factory_button').click(function()
-    {
-        gras_chart_factory_handle_input(registry);
-    });
-
-    //init the chart selection input
-    $.each(gras_chart_get_registry(), function(index, options)
-    {
-        registry.chart_factories[options.key] = options.factory;
-        var option = $('<option />').attr({value: options.key});
-        option.text(options.name);
-        $('#chart_type_selector').append(option);
-    });
-
-    //init overall config gui element for rate
-    var overall_rate = $('#chart_update_rate');
-    overall_rate.val(registry.overall_rate);
-    overall_rate.change(function()
-    {
-        registry.overall_rate = overall_rate.val();
-    });
-
-    //init overall config gui element for activity
-    registry.overall_active = true;
-    var overall_active = $('#chart_active_state');
-    overall_active.attr('checked', registry.overall_active);
-    overall_active.change(function()
-    {
-        registry.overall_active = overall_active.is(':checked');
-        if (registry.overall_active) gras_query_stats(registry);
-        else window.clearInterval(registry.timeout_handle);
-    });
-}
diff --git a/python/gras/stats/chart_handler_breakdown.js b/python/gras/stats/chart_handler_breakdown.js
deleted file mode 100644
index 8e90fc3..0000000
--- a/python/gras/stats/chart_handler_breakdown.js
+++ /dev/null
@@ -1,37 +0,0 @@
-function GrasChartHandlerBreakdown(args)
-{
-    //input checking
-    if (args.block_ids.length != 1) throw gras_error_dialog(
-        "GrasChartHandlerBreakdown",
-        "Error making handler breakdown chart.\n"+
-        "Specify only one block for this chart."
-    );
-
-    //save enable
-    this.block_id = args.block_ids[0];
-
-    //make new chart
-    this.chart = new google.visualization.PieChart(args.panel);
-
-    this.title = "Handler Breakdown - " + this.block_id;
-}
-
-GrasChartHandlerBreakdown.prototype.update = function(point)
-{
-    var percents = gras_extract_percent_times(point, this.block_id);
-    var data = google.visualization.arrayToDataTable([
-          ['Task', 'Percent'],
-          ['Work prep', percents['prep']],
-          ['Work task', percents['work']],
-          ['Work post', percents['post']],
-          ['Input tasks', percents['input']],
-          ['Output tasks', percents['output']],
-    ]);
-
-    var options = {
-        width:GRAS_CHARTS_STD_WIDTH,
-        chartArea:{left:5,top:0,right:5,bottom:0,width:"100%",height:"100%"},
-    };
-
-    this.chart.draw(data, options);
-};
diff --git a/python/gras/stats/chart_overall_throughput.js b/python/gras/stats/chart_overall_throughput.js
deleted file mode 100644
index 4947479..0000000
--- a/python/gras/stats/chart_overall_throughput.js
+++ /dev/null
@@ -1,46 +0,0 @@
-function GrasChartOverallThroughput(args)
-{
-    //save enables
-    this.ids = args.block_ids;
-
-    //input checking
-    if (this.ids.length == 0) throw gras_error_dialog(
-        "GrasChartOverallThroughput",
-        "Error making overall thoughput chart.\n"+
-        "Specify at least 1 block for this chart."
-    );
-
-    //make new chart
-    this.chart = new google.visualization.LineChart(args.panel);
-
-    this.title = "Overall Throughput vs Time";
-    this.history = new Array();
-}
-
-GrasChartOverallThroughput.prototype.update = function(point)
-{
-    this.history.push(point);
-    if (this.history.length == 1) this.p0 = point;
-    if (this.history.length < 2) return;
-    if (this.history.length > 10) this.history.splice(0, 1);
-
-    var data_set = [['Throughput'].concat(this.ids)];
-    for (var i = 1; i < this.history.length; i++)
-    {
-        var row = new Array();
-        row.push(gras_extract_stat_time_delta(this.p0, this.history[i]).toFixed(2).toString());
-        for (var j = 0; j < this.ids.length; j++)
-        {
-            row.push(gras_extract_throughput_delta(this.history[i-1], this.history[i], this.ids[j])/1e6);
-        }
-        data_set.push(row);
-    }
-
-    var chart_data = google.visualization.arrayToDataTable(data_set);
-    var options = {
-        width:GRAS_CHARTS_STD_WIDTH*2,
-        chartArea:{left:0,top:0,right:0,bottom:0,width:"100%",height:"85%"},
-        legend: {'position': 'bottom'},
-    };
-    this.chart.draw(chart_data, options);
-};
diff --git a/python/gras/stats/chart_overhead_compare.js b/python/gras/stats/chart_overhead_compare.js
deleted file mode 100644
index c373142..0000000
--- a/python/gras/stats/chart_overhead_compare.js
+++ /dev/null
@@ -1,37 +0,0 @@
-function GrasChartOverheadCompare(args)
-{
-    //save enables
-    this.ids = args.block_ids;
-
-    //input checking
-    if (this.ids.length <= 1) throw gras_error_dialog(
-        "GrasChartOverheadCompare",
-        "Error making overhead compare chart.\n"+
-        "Specify at least 2 blocks for this chart."
-    );
-
-    //make new chart
-    this.chart = new google.visualization.PieChart(args.panel);
-
-    this.title = "Overhead Comparison";
-}
-
-GrasChartOverheadCompare.prototype.update = function(point)
-{
-    var data_set = new Array();
-    data_set.push(['Task', 'Percent']);
-    $.each(this.ids, function(index, id)
-    {
-        var percents = gras_extract_percent_times(point, id);
-        data_set.push([id, percents['total']]);
-    });
-
-    var data = google.visualization.arrayToDataTable(data_set)
-
-    var options = {
-        width:GRAS_CHARTS_STD_WIDTH,
-        chartArea:{left:5,top:0,right:5,bottom:0,width:"100%",height:"100%"},
-    };
-
-    this.chart.draw(data, options);
-};
diff --git a/python/gras/stats/chart_total_io_counts.js b/python/gras/stats/chart_total_io_counts.js
deleted file mode 100644
index 5aaaf24..0000000
--- a/python/gras/stats/chart_total_io_counts.js
+++ /dev/null
@@ -1,62 +0,0 @@
-function GrasChartTotalIoCounts(args)
-{
-    //input checking
-    if (args.block_ids.length != 1) throw gras_error_dialog(
-        "GrasChartTotalIoCounts",
-        "Error making total IO counts chart.\n"+
-        "Specify only one block for this chart."
-    );
-
-    //settings
-    this.block_id = args.block_ids[0];
-    this.div = $('<div />').attr({class:'chart_total_io_counts'});
-    $(args.panel).append(this.div);
-    this.title = "I/O Totals - " + this.block_id;
-}
-
-GrasChartTotalIoCounts.prototype.update = function(point)
-{
-    var block_data = $('block[id="' + this.block_id + '"]', point);
-    var ul = $('<ul />');
-    $('ul', this.div).remove(); //clear old lists
-    this.div.append(ul);
-
-    {
-        var init_time = parseInt($('init_time', block_data).text());
-        var stats_time = parseInt($('stats_time', block_data).text());
-        var tps = parseInt($('tps', block_data).text());
-        var duration = (stats_time - init_time)/tps;
-        var li = $('<li />');
-        var strong = $('<strong />').text('Elapsed' + ': ');
-        var span = $('<span />').text(duration.toFixed(2).toString() + ' secs');
-        li.append(strong);
-        li.append(span);
-        ul.append(li);
-    }
-
-    var stuff = [
-        ['Input', 'items', 'items_consumed'],
-        ['Input', 'tags', 'tags_consumed'],
-        ['Input', 'msgs', 'msgs_consumed'],
-        ['Output', 'items', 'items_produced'],
-        ['Output', 'tags', 'tags_produced'],
-        ['Output', 'msgs', 'msgs_produced'],
-    ];
-
-    $.each(stuff, function(contents_i, contents)
-    {
-        var dir = contents[0];
-        var units = contents[1];
-        var key = contents[2];
-        $(key, block_data).each(function(index, elem)
-        {
-            var count = parseInt($(elem).text());
-            var li = $('<li />');
-            var strong = $('<strong />').text(dir + index.toString() + ': ');
-            var span = $('<span />').text(count.toString() + ' ' + units);
-            li.append(strong);
-            li.append(span);
-            if (count > 0) ul.append(li);
-        });
-    });
-}
diff --git a/python/gras/stats/main.css b/python/gras/stats/main.css
deleted file mode 100644
index b5f62f1..0000000
--- a/python/gras/stats/main.css
+++ /dev/null
@@ -1,161 +0,0 @@
-*{
-margin:0px;
-padding:0px;
-}
-
-body{
-font-family:Arial, Helvetica, sans-serif;
-font-size:9pt;
-color:black;
-background-color:white;
-}
-
-.chart_designer_block_close
-{
-float:right;
-}
-
-#chart_designer_blocks div
-{
-float:left;
-}
-
-#chart_designer_blocks label
-{
-text-decoration:underline;
-}
-
-#chart_designer_blocks input
-{
-margin-right:10px;
-margin-left:2px;
-}
-
-.chart_total_io_counts li
-{
-list-style-type:none;
-text-align: left;
-padding: 0px;
-margin: 0px;
-font-size:90%;
-}
-
-.chart_container
-{
-float:left;
-}
-
-#page{
-padding:10px;
-color:inherit;
-background-color:inherit;
-}
-
-#page h1{
-font-size:130%;
-border-left:1px solid #333333;
-border-bottom:1px solid #333333;
-text-align:left;
-padding:10px 0px 10px 10px;
-margin:10px 5px 20px 5px;
-color:#333333;
-background-color:inherit;
-}
-
-#page h2{
-font-size:130%;
-text-align:center;
-padding:20px 0px 10px 0px;
-color:#333333;
-background-color:inherit;
-}
-
-#page h3{
-font-size:110%;
-text-align:left;
-padding:15px 0px 5px 10px;
-text-decoration:underline;
-color:#333333;
-background-color:inherit;
-}
-
-#page h4{
-font-size:105%;
-text-align:center;
-padding:5px 0px 3px 0px;
-text-decoration:underline;
-}
-
-#page p{
-text-indent:20px;
-padding:5px 0px 5px 10px;
-}
-
-#page strong{
-}
-
-#page em{
-}
-
-#page li{
-padding:5px 5px 0px 3px;
-}
-
-#page ul, #page ol{
-padding:5px 0px 5px 40px;
-}
-
-#page img{
-margin:10px auto 10px auto;
-display:block;
-border-style:none;
-}
-
-#page a:link, #page a:visited{
-color:#236B8E;
-background-color:inherit;
-text-decoration:none;
-}
-
-#page a:hover{
-color:#4985D6;
-background-color:inherit;
-text-decoration:none;
-}
-
-#page pre{
-border:1px inset #333333;
-padding:5px;
-margin:10px 5px 10px 5px;
-color:inherit;
-background-color:#FCFCFC;
-font-size:90%;
-}
-
-#page hr{
-margin:10px 0px 0px 0px;
-}
-
-#page table{
-padding:5px;
-}
-
-#page th{
-padding:3px;
-border:1px solid #333333;
-text-align:center;
-color:inherit;
-background-color:#ECECEC;
-}
-
-#page tr{
-}
-
-#page td{
-padding:3px;
-border:1px solid #333333;
-text-align:center;
-color:inherit;
-background-color:#FCFCFC;
-}
-
diff --git a/python/gras/stats/main.html b/python/gras/stats/main.html
deleted file mode 100644
index eeb221d..0000000
--- a/python/gras/stats/main.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
-    <meta http-equiv="Content-Style-Type" content="text/css" />
-    <title>GRAS Status Monitor</title>
-    <link rel="stylesheet" type="text/css" href="/main.css" />
-    <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
-    <script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
-    <script type="text/javascript" src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
-    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
-    <script type="text/javascript" src="/utils.js"></script>
-    <script type="text/javascript" src="/chart_factory.js"></script>
-    <script type="text/javascript" src="/chart_overhead_compare.js"></script>
-    <script type="text/javascript" src="/chart_overall_throughput.js"></script>
-    <script type="text/javascript" src="/chart_handler_breakdown.js"></script>
-    <script type="text/javascript" src="/chart_total_io_counts.js"></script>
-    <script type="text/javascript" src="/main.js"></script>
-    <script type="text/javascript">
-        google.load('visualization', '1.0', {'packages':['corechart']});
-        google.setOnLoadCallback(gras_stats_main);
-    </script>
-</head>
-
-<body id='page'>
-    <div id="chart_designer">
-        <table>
-            <tr>
-                <th id="top_name">Blocks Available</th>
-                <th>Chart Types</th>
-                <th>Global Options</th>
-            </tr>
-            <tr>
-                <td id="chart_designer_blocks" rowspan='2'></td>
-                <td><select id="chart_type_selector" /></td>
-                <td><label>Updates/sec:</label><input id="chart_update_rate" type="number" name="rate" min="1" max="10" size="4" /></td>
-            </tr>
-            <tr>
-                <td><input type="submit" value="Create New Chart" id="chart_factory_button" /></td>
-                <td><label>Active?</label><input id="chart_active_state" type="checkbox" name="active" /></td>
-            </tr>
-        </table>
-    </div>
-    <div id="charts_panel"></div>
-    <div style="display:none" id="div-dialog-warning">
-    </div>
-</body>
-
-</html>
diff --git a/python/gras/stats/main.js b/python/gras/stats/main.js
deleted file mode 100644
index a27c0b7..0000000
--- a/python/gras/stats/main.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/***********************************************************************
- * Some constants
- **********************************************************************/
-var GRAS_CHARTS_STD_WIDTH = 250;
-
-/***********************************************************************
- * Stats registry data structure
- **********************************************************************/
-var GrasStatsRegistry = function()
-{
-    this.init = false;
-    this.overall_rate = 2.0;
-    this.overall_active = true;
-    this.block_ids = new Array();
-    this.top_id = 'top';
-    this.online = true;
-    this.offline_count = 0;
-}
-
-/***********************************************************************
- * Query stats
- **********************************************************************/
-var gras_query_stats = function(registry)
-{
-    $.ajax({
-        type: "GET",
-        async: true,
-        url: "/stats.xml",
-        dataType: "xml",
-        success: function(xml)
-        {
-            registry.online = true;
-            gras_chart_factory_online(registry);
-            if (registry.overall_active)
-            {
-                if ($(xml, "gras_stats") !== undefined)
-                {
-                    if (!registry.init)
-                    {
-                        gras_chart_factory_setup(registry, xml);
-                        try{gras_chart_load(registry);}catch(e){}
-                        registry.init = true;
-                    }
-                    $.each(registry.active_charts, function(index, chart_info)
-                    {
-                        chart_info.chart.update(xml);
-                    });
-                }
-
-                registry.timeout_handle = window.setTimeout(function()
-                {
-                    gras_query_stats(registry);
-                }, Math.round(1000/registry.overall_rate));
-            }
-        },
-        error: function()
-        {
-            registry.online = false;
-            gras_chart_factory_online(registry);
-            registry.timeout_handle = window.setTimeout(function()
-            {
-                gras_query_stats(registry);
-            }, 1000);
-        },
-    });
-}
-
-/***********************************************************************
- * Init
- **********************************************************************/
-var gras_stats_main = function()
-{
-    var registry = new GrasStatsRegistry();
-    gras_chart_factory_init(registry);
-    gras_query_stats(registry);
-}
diff --git a/python/gras/stats/utils.js b/python/gras/stats/utils.js
deleted file mode 100644
index f5e5ee8..0000000
--- a/python/gras/stats/utils.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/***********************************************************************
- * Utility functions for stats
- **********************************************************************/
-var gras_extract_total_items = function(point, id)
-{
-    var block_data = $('block[id="' + id + '"]', point);
-    var total_items = 0;
-    $('items_consumed,items_produced', block_data).each(function()
-    {
-        total_items += parseInt($(this).text());
-    });
-    return total_items;
-}
-
-var gras_extract_throughput_delta = function(p0, p1, id)
-{
-    var d0 = $('block[id="' + id + '"]', p0);
-    var d1 = $('block[id="' + id + '"]', p1);
-    var t0 = parseInt($('stats_time', d0).text());
-    var t1 = parseInt($('stats_time', d1).text());
-    var tps = parseInt($('tps', d0).text());
-    var items0 = gras_extract_total_items(p0, id);
-    var items1 = gras_extract_total_items(p1, id);
-    return ((items1-items0)*tps)/(t1-t0);
-}
-
-var gras_extract_throughput = function(point, id)
-{
-    var block_data = $('block[id="' + id + '"]', point);
-    var start_time = parseInt($('start_time', block_data).text());
-    var stats_time = parseInt($('stats_time', block_data).text());
-    var tps = parseInt($('tps', block_data).text());
-    var total_items = gras_extract_total_items(point, id);
-    return (total_items*tps)/(stats_time-start_time);
-}
-
-var gras_extract_stat_time_delta = function(p0, p1)
-{
-    var t0 = parseInt($('now', p0).text());
-    var t1 = parseInt($('now', p1).text());
-    var tps = parseInt($('tps', p0).first().text());
-    return (t1-t0)/(tps);
-}
-
-var gras_extract_percent_times = function(point, id)
-{
-    var block_data = $('block[id="' + id + '"]', point);
-    var data = {
-        prep: parseInt($('total_time_prep', block_data).text()),
-        work: parseInt($('total_time_work', block_data).text()),
-        post: parseInt($('total_time_post', block_data).text()),
-        input: parseInt($('total_time_input', block_data).text()),
-        output: parseInt($('total_time_output', block_data).text()),
-    };
-    var total = 0;
-    $.each(data, function(key, val)
-    {
-        total += val;
-    });
-    data['total'] = total;
-    return data;
-}
-
-var gras_animate_show_hide = function(elem, show)
-{
-    if (show) elem.slideDown("fast");
-    else elem.slideUp("fast");
-}
-
-var gras_error_dialog = function(error_title, error_text)
-{
-    $("#div-dialog-warning").text(error_text);
-    $("#div-dialog-warning").dialog({
-        title: error_title,
-        resizable: false,
-        height: 160,
-        modal: true,
-        buttons: {
-            "Ok" : function () {
-                $(this).dialog("close");
-            }
-        }
-    }).parent().addClass("ui-state-error");
-}
-- 
cgit