changeset 2538:464c6c6692d6

Beautified entire project.
author Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk>
date Mon, 14 Nov 2016 14:17:03 +0000
parents 527020a63203
children bc9a025e7e10 6ff61a4f62a8
files analysis/analysis.css analysis/analysis.js analysis/index.html css/core.css index.html interfaces/AB.css interfaces/AB.js interfaces/ABX.css interfaces/ABX.js interfaces/ape.css interfaces/ape.js interfaces/blank.js interfaces/discrete.css interfaces/discrete.js interfaces/horizontal-sliders.css interfaces/horizontal-sliders.js interfaces/mushra.css interfaces/mushra.js interfaces/timeline.css js/WAVE.js js/loader.js js/loudness.js js/specification.js php/comment_parser.php php/get_filtered_count.php php/get_filtered_score.php php/get_tests.php php/pool.php php/rel2abs.php php/save.php php/score_parser.php python/comment_parser.html test.html test_create.html test_create/custom.css test_create/interface-specs.xml test_create/style.css tests/examples/AB_example.xml tests/examples/APE_example.xml tests/examples/horizontal_example.xml tests/examples/mushra_example.xml tests/examples/radio_example.xml tests/examples/timeline.xml xml/scaledefinitions.xml xml/test-schema.xsd
diffstat 45 files changed, 5292 insertions(+), 5588 deletions(-) [+]
line wrap: on
line diff
--- a/analysis/analysis.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/analysis/analysis.css	Mon Nov 14 14:17:03 2016 +0000
@@ -5,12 +5,12 @@
 div.code {
     margin: 5px;
     padding-left: 15px;
-    background-color: rgb(200,200,200);
+    background-color: rgb(200, 200, 200);
     border: 2px dashed black;
 }
-table td tr{
+table td tr {
     padding: 5px;
 }
-div.filter-entry{
+div.filter-entry {
     padding: 5px;
-}
\ No newline at end of file
+}
--- a/analysis/analysis.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/analysis/analysis.js	Mon Nov 14 14:17:03 2016 +0000
@@ -1,31 +1,26 @@
 /*
-* Analysis script for WAET
-*/
+ * Analysis script for WAET
+ */
 
 // Firefox does not have an XMLDocument.prototype.getElementsByName
 // and there is no searchAll style command, this custom function will
 // search all children recusrively for the name. Used for XSD where all
 // element nodes must have a name and therefore can pull the schema node
-XMLDocument.prototype.getAllElementsByName = function(name)
-{
+XMLDocument.prototype.getAllElementsByName = function (name) {
     name = String(name);
     var selected = this.documentElement.getAllElementsByName(name);
     return selected;
 }
 
-Element.prototype.getAllElementsByName = function(name)
-{
+Element.prototype.getAllElementsByName = function (name) {
     name = String(name);
     var selected = [];
     var node = this.firstElementChild;
-    while(node != null)
-    {
-        if (node.getAttribute('name') == name)
-        {
+    while (node != null) {
+        if (node.getAttribute('name') == name) {
             selected.push(node);
         }
-        if (node.childElementCount > 0)
-        {
+        if (node.childElementCount > 0) {
             selected = selected.concat(node.getAllElementsByName(name));
         }
         node = node.nextElementSibling;
@@ -33,26 +28,21 @@
     return selected;
 }
 
-XMLDocument.prototype.getAllElementsByTagName = function(name)
-{
+XMLDocument.prototype.getAllElementsByTagName = function (name) {
     name = String(name);
     var selected = this.documentElement.getAllElementsByTagName(name);
     return selected;
 }
 
-Element.prototype.getAllElementsByTagName = function(name)
-{
+Element.prototype.getAllElementsByTagName = function (name) {
     name = String(name);
     var selected = [];
     var node = this.firstElementChild;
-    while(node != null)
-    {
-        if (node.nodeName == name)
-        {
+    while (node != null) {
+        if (node.nodeName == name) {
             selected.push(node);
         }
-        if (node.childElementCount > 0)
-        {
+        if (node.childElementCount > 0) {
             selected = selected.concat(node.getAllElementsByTagName(name));
         }
         node = node.nextElementSibling;
@@ -62,15 +52,12 @@
 
 // Firefox does not have an XMLDocument.prototype.getElementsByName
 if (typeof XMLDocument.prototype.getElementsByName != "function") {
-    XMLDocument.prototype.getElementsByName = function(name)
-    {
+    XMLDocument.prototype.getElementsByName = function (name) {
         name = String(name);
         var node = this.documentElement.firstElementChild;
         var selected = [];
-        while(node != null)
-        {
-            if (node.getAttribute('name') == name)
-            {
+        while (node != null) {
+            if (node.getAttribute('name') == name) {
                 selected.push(node);
             }
             node = node.nextElementSibling;
@@ -80,41 +67,42 @@
 }
 
 var chartContext, testData;
-window.onload = function() {
+window.onload = function () {
     // Load the Visualization API and the corechart package.
-    google.charts.load('current', {'packages':['corechart']});
+    google.charts.load('current', {
+        'packages': ['corechart']
+    });
     chartContext = new Chart();
     testData = new Data();
 }
 
 function get(url) {
-  // Return a new promise.
-  return new Promise(function(resolve, reject) {
-    // Do the usual XHR stuff
-    var req = new XMLHttpRequest();
-    req.open('GET', url);
-    req.onload = function() {
-      // This is called even on 404 etc
-      // so check the status
-      if (req.status == 200) {
-        // Resolve the promise with the response text
-        resolve(req.response);
-      }
-      else {
-        // Otherwise reject with the status text
-        // which will hopefully be a meaningful error
-        reject(Error(req.statusText));
-      }
-    };
+    // Return a new promise.
+    return new Promise(function (resolve, reject) {
+        // Do the usual XHR stuff
+        var req = new XMLHttpRequest();
+        req.open('GET', url);
+        req.onload = function () {
+            // This is called even on 404 etc
+            // so check the status
+            if (req.status == 200) {
+                // Resolve the promise with the response text
+                resolve(req.response);
+            } else {
+                // Otherwise reject with the status text
+                // which will hopefully be a meaningful error
+                reject(Error(req.statusText));
+            }
+        };
 
-    // Handle network errors
-    req.onerror = function() {
-      reject(Error("Network Error"));
-    };
+        // Handle network errors
+        req.onerror = function () {
+            reject(Error("Network Error"));
+        };
 
-    // Make the request
-    req.send();
-  });
+        // Make the request
+        req.send();
+    });
 }
 
 function arrayMean(values) {
@@ -128,15 +116,17 @@
 
 function percentile(values, p) {
     //http://web.stanford.edu/class/archive/anthsci/anthsci192/anthsci192.1064/handouts/calculating%20percentiles.pdf
-    values.sort( function(a,b) {return a - b;} );
+    values.sort(function (a, b) {
+        return a - b;
+    });
     // get ordinal rank
-    var index = values.length*p/100;
+    var index = values.length * p / 100;
     var k = Math.floor(index);
     if (k == index) {
         return values[k];
     } else {
-        var f = index-k;
-        var x_int = (1-f)*values[k]+f*values[k+1];
+        var f = index - k;
+        var x_int = (1 - f) * values[k] + f * values[k + 1];
         return x_int;
     }
 }
@@ -166,19 +156,19 @@
 function boxplotRow(array) {
     // Take an array of element values and return array of computed intervals
     var result = {
-        median : percentile(array,50),
-        pct25 : percentile(array,25),
-        pct75 : percentile(array,75),
-        IQR : null,
+        median: percentile(array, 50),
+        pct25: percentile(array, 25),
+        pct75: percentile(array, 75),
+        IQR: null,
         min: null,
         max: null,
         outliers: new Array()
     }
-    result.IQR = result.pct75-result.pct25;
+    result.IQR = result.pct75 - result.pct25;
     var rest = [];
-    var pct75_IQR = result.pct75+1.5*result.IQR;
-    var pct25_IQR = result.pct25-1.5*result.IQR;
-    for (var i=0; i<array.length; i++) {
+    var pct75_IQR = result.pct75 + 1.5 * result.IQR;
+    var pct25_IQR = result.pct25 - 1.5 * result.IQR;
+    for (var i = 0; i < array.length; i++) {
         //outliers, ranger above pct75+1.5*IQR or below pct25-1.5*IQR
         var point = array[i];
         if (point > pct75_IQR || point < pct25_IQR) {
@@ -190,23 +180,27 @@
     result.max = arrayMax(rest);
     result.min = arrayMin(rest);
     return result;
-    
+
 }
 
-function arrayHistogram(values,steps,min,max) {
+function arrayHistogram(values, steps, min, max) {
     if (steps == undefined) {
         steps = 0.25;
         console.log("Warning: arrayHistogram called without steps size set, default to 0.25");
     }
-    if (min == undefined) {min = arrayMin(values);}
-    if (max == undefined) {max = arrayMax(values);}
+    if (min == undefined) {
+        min = arrayMin(values);
+    }
+    if (max == undefined) {
+        max = arrayMax(values);
+    }
     var histogram = [];
     var index = min;
-    while(index < max) {
+    while (index < max) {
         histogram.push({
             marker: index,
             lt: index,
-            rt: index+steps,
+            rt: index + steps,
             count: 0
         });
         index += steps;
@@ -225,13 +219,13 @@
 function Chart() {
     this.valueData;
     this.charts = [];
-    
-    this.chartObject = function(name) {
+
+    this.chartObject = function (name) {
         // Create the charting object
         this.name = name;
         this.root = document.createElement("div");
         this.root.className = "chart-holder";
-        this.root.setAttribute("name",name);
+        this.root.setAttribute("name", name);
         this.chartDOM = document.createElement("div");
         this.tableDOM = document.createElement("div");
         this.latexDOM = document.createElement("div");
@@ -242,30 +236,31 @@
         this.print = document.createElement("button");
         this.sortDataButton = document.createElement("button");
         this.sortDataButton.textContent = "Sort by Data";
-        this.sortDataButton.addEventListener("click",this);
-        this.sortDataButton.setAttribute("name","sort-data");
+        this.sortDataButton.addEventListener("click", this);
+        this.sortDataButton.setAttribute("name", "sort-data");
         this.sortNameButton = document.createElement("button");
         this.sortNameButton.textContent = "Sort by Name";
-        this.sortNameButton.addEventListener("click",this);
-        this.sortNameButton.setAttribute("name","sort-name");
-        this.draw = function() {
-            if (this.chart == undefined) {return;}
+        this.sortNameButton.addEventListener("click", this);
+        this.sortNameButton.setAttribute("name", "sort-name");
+        this.draw = function () {
+            if (this.chart == undefined) {
+                return;
+            }
             this.tableDOM.innerHTML = null;
             this.latexDOM.innerHTML = null;
             this.buildTable();
             this.writeLatex();
-            this.chart.draw(this.data,this.options);
+            this.chart.draw(this.data, this.options);
         }
-        this.sortData = function() {
+        this.sortData = function () {
             this.data.sort(1);
         }
-        this.sortName = function() {
+        this.sortName = function () {
             this.data.sort(0);
         }
-        this.handleEvent = function() {
+        this.handleEvent = function () {
             // Only used to handle the chart.event.addListener(this,'ready') callback
-            switch(event.currentTarget.getAttribute("name"))
-            {
+            switch (event.currentTarget.getAttribute("name")) {
                 case "download":
                     window.open(this.chart.getImageURI());
                     break;
@@ -279,7 +274,7 @@
                     break;
             }
         }
-        
+
         this.root.appendChild(this.chartDOM);
         this.root.appendChild(this.tableDOM);
         this.root.appendChild(this.latexDOM);
@@ -287,16 +282,15 @@
         this.root.appendChild(this.sortNameButton);
         this.root.appendChild(this.print);
         this.print.textContent = "Download";
-        this.print.setAttribute("name","download");
-        this.print.addEventListener("click",this);
+        this.print.setAttribute("name", "download");
+        this.print.addEventListener("click", this);
         this.root.appendChild(this.downloadDOM);
-        this.buildTable = function() {
+        this.buildTable = function () {
             var table = document.createElement("table");
             table.border = "1";
             var numRows = this.data.getNumberOfRows();
             var numColumns = this.data.getNumberOfColumns();
-            for (var columnIndex=0; columnIndex<numColumns; columnIndex++)
-            {
+            for (var columnIndex = 0; columnIndex < numColumns; columnIndex++) {
                 var tableTitle = this.data.getColumnLabel(columnIndex);
                 if (tableTitle != "") {
                     var table_row = document.createElement('tr');
@@ -304,13 +298,11 @@
                     var row_title = document.createElement('td');
                     table_row.appendChild(row_title);
                     row_title.textContent = tableTitle;
-                    for (var rowIndex=0; rowIndex<numRows; rowIndex++)
-                    {
+                    for (var rowIndex = 0; rowIndex < numRows; rowIndex++) {
                         var row_entry = document.createElement('td');
                         table_row.appendChild(row_entry);
-                        var entry = this.data.getValue(rowIndex,columnIndex);
-                        if (isFinite(Number(entry)))
-                        {
+                        var entry = this.data.getValue(rowIndex, columnIndex);
+                        if (isFinite(Number(entry))) {
                             entry = String(Number(entry).toFixed(4));
                         }
                         row_entry.textContent = entry;
@@ -319,7 +311,7 @@
             }
             this.tableDOM.appendChild(table);
         };
-        this.writeLatex = function() {
+        this.writeLatex = function () {
             var numRows = this.data.getNumberOfRows();
             var numColumns = this.data.getNumberOfColumns();
             var root = document.createElement("div");
@@ -329,25 +321,23 @@
             var start = document.createElement("p");
             start.textContent = "\\" + "begin{tabular}{|l|";
             holder.appendChild(start);
-            for (var i=0; i<numRows; i++) {
-                start.textContent = start.textContent+"c|";
+            for (var i = 0; i < numRows; i++) {
+                start.textContent = start.textContent + "c|";
             }
             start.textContent = start.textContent.concat("}");
             // Now write the rows:
-            for (var rIndex=0; rIndex<numColumns; rIndex++) {
+            for (var rIndex = 0; rIndex < numColumns; rIndex++) {
                 var tableTitle = this.data.getColumnLabel(rIndex);
-                if(tableTitle != "")
-                {
+                if (tableTitle != "") {
                     var row = document.createElement("p");
                     row.textContent = tableTitle.concat(" & ");
-                    for (var cIndex=0; cIndex<numRows; cIndex++) {
-                        var entry = this.data.getValue(cIndex,rIndex);
-                        if (isFinite(Number(entry)))
-                        {
+                    for (var cIndex = 0; cIndex < numRows; cIndex++) {
+                        var entry = this.data.getValue(cIndex, rIndex);
+                        if (isFinite(Number(entry))) {
                             entry = String(Number(entry).toFixed(4));
                         }
                         row.textContent = row.textContent.concat(entry);
-                        if (cIndex < numRows-1) {
+                        if (cIndex < numRows - 1) {
                             row.textContent = row.textContent.concat(" & ");
                         } else {
                             row.textContent = row.textContent.concat(" \\\\ \\hline");
@@ -364,86 +354,98 @@
             this.latexDOM.appendChild(root);
         }
     }
-    
-    this.clear = function() {
+
+    this.clear = function () {
         var inject = document.getElementById("test-pages");
         for (var chart of this.charts) {
             inject.removeChild(chart.root);
         }
         this.charts = [];
     }
-    
-    this.drawTestMean = function() {
+
+    this.drawTestMean = function () {
         // This draws one bargraph per axis with every test element on
         if (this.valueData == null) {
             console.log("Error - Data not loaded");
             return;
         }
         var chartList = [];
-        
+
         // Create the data table
         for (var page of this.valueData.pages) {
             for (var element of page.elements) {
                 for (var axis of element.axis) {
                     // Find the axis
-                    var axisChart = chartList.find(function(element,index,array){
-                        if (element.name == this) {return true;} else {return false;}
-                    },"mean-test-"+axis.name);
+                    var axisChart = chartList.find(function (element, index, array) {
+                        if (element.name == this) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    }, "mean-test-" + axis.name);
                     if (axisChart == null) {
-                        axisChart = new this.chartObject("mean-test-"+axis.name);
+                        axisChart = new this.chartObject("mean-test-" + axis.name);
                         axisChart.options = {
-                            'title':'Mean of axis: '+axis.name,
-                            'width':window.innerWidth*0.9,
-                            'height':(window.innerWidth*0.9)/1.77
+                            'title': 'Mean of axis: ' + axis.name,
+                            'width': window.innerWidth * 0.9,
+                            'height': (window.innerWidth * 0.9) / 1.77
                         }
-                        axisChart.data.addColumn('string','id');
-                        axisChart.data.addColumn('number',axis.name);
+                        axisChart.data.addColumn('string', 'id');
+                        axisChart.data.addColumn('number', axis.name);
                         chartList.push(axisChart);
                         document.getElementById("test-pages").appendChild(axisChart.root);
                     }
                     var mean = arrayMean(axis.values);
-                    axisChart.data.addRow([element.id,mean]);
+                    axisChart.data.addRow([element.id, mean]);
                 }
             }
         }
-        
+
         // Build and push charts
         for (var chart of chartList) {
             chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
-            chart.chart.draw(chart.data,chart.options);
+            chart.chart.draw(chart.data, chart.options);
             chart.buildTable();
             chart.writeLatex();
             this.charts.push(chart);
         }
     }
-    
-    this.drawTestBoxplot = function() {
+
+    this.drawTestBoxplot = function () {
         if (this.valueData == null) {
             console.log("Error - Data not loaded");
             return;
         }
         var chartList = [];
-        
+
         // Creates one chart per axis
-        
+
         // Create the data table
         for (var page of this.valueData.pages) {
             for (var element of page.elements) {
                 for (var axis of element.axis) {
                     // Find the axis
-                    var axisChart = chartList.find(function(element,index,array){
-                        if (element.name == this) {return true;} else {return false;}
-                    },"boxplot-test-"+axis.name);
+                    var axisChart = chartList.find(function (element, index, array) {
+                        if (element.name == this) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    }, "boxplot-test-" + axis.name);
                     if (axisChart == null) {
                         // Axis chart doesn't exist
-                        axisChart = new this.chartObject("boxplot-test-"+axis.name);
+                        axisChart = new this.chartObject("boxplot-test-" + axis.name);
                         axisChart.options = {
-                            'title':'Boxplot of axis '+axis.name,
-                            'width':window.innerWidth*0.9,
-                            'height':(window.innerWidth*0.9)/1.77,
-                            legend: {position: 'none'},
+                            'title': 'Boxplot of axis ' + axis.name,
+                            'width': window.innerWidth * 0.9,
+                            'height': (window.innerWidth * 0.9) / 1.77,
+                            legend: {
+                                position: 'none'
+                            },
                             lineWidth: 0,
-                            series: [{'color': '#D3362D'}],
+                            series: [{
+                                'color': '#D3362D'
+                            }],
                             intervals: {
                                 barWidth: 1,
                                 boxWidth: 1,
@@ -463,32 +465,52 @@
                                 }
                             }
                         };
-                        axisChart.data.addColumn('string','id');
-                        axisChart.data.addColumn('number','median');
-                        axisChart.data.addColumn({id:'max',type:'number',role:'interval'});
-                        axisChart.data.addColumn({id:'min',type:'number',role:'interval'});
-                        axisChart.data.addColumn({id:'firstQuartile',type:'number',role:'interval'});
-                        axisChart.data.addColumn({id:'median',type:'number',role:'interval'});
-                        axisChart.data.addColumn({id:'thirdQuartile',type:'number',role:'interval'});
+                        axisChart.data.addColumn('string', 'id');
+                        axisChart.data.addColumn('number', 'median');
+                        axisChart.data.addColumn({
+                            id: 'max',
+                            type: 'number',
+                            role: 'interval'
+                        });
+                        axisChart.data.addColumn({
+                            id: 'min',
+                            type: 'number',
+                            role: 'interval'
+                        });
+                        axisChart.data.addColumn({
+                            id: 'firstQuartile',
+                            type: 'number',
+                            role: 'interval'
+                        });
+                        axisChart.data.addColumn({
+                            id: 'median',
+                            type: 'number',
+                            role: 'interval'
+                        });
+                        axisChart.data.addColumn({
+                            id: 'thirdQuartile',
+                            type: 'number',
+                            role: 'interval'
+                        });
                         chartList.push(axisChart);
                         document.getElementById("test-pages").appendChild(axisChart.root);
                     }
                     var result = boxplotRow(axis.values);
-                    axisChart.data.addRow([element.id,result.median,result.max,result.min,result.pct25,result.median,result.pct75]);
+                    axisChart.data.addRow([element.id, result.median, result.max, result.min, result.pct25, result.median, result.pct75]);
                 }
             }
         }
         // Build and push charts
         for (var chart of chartList) {
             chart.chart = new google.visualization.LineChart(chart.chartDOM);
-            chart.chart.draw(chart.data,chart.options);
+            chart.chart.draw(chart.data, chart.options);
             chart.buildTable();
             chart.writeLatex();
             this.charts.push(chart);
         }
     }
-    
-    this.drawPageMean = function() {
+
+    this.drawPageMean = function () {
         // First we must get the value data
         if (this.valueData == null) {
             console.log("Error - Data not loaded");
@@ -496,22 +518,22 @@
         }
         // We create one plot per page
         for (var page of this.valueData.pages) {
-            
+
             // Create the chart resulting point
-            var chart = new this.chartObject("mean-page-"+page.id);
+            var chart = new this.chartObject("mean-page-" + page.id);
             document.getElementById("test-pages").appendChild(chart.root);
-            
+
             // Create the data table
-            chart.data.addColumn('string','id');
+            chart.data.addColumn('string', 'id');
             // Get axis labels
             for (var axis of page.elements[0].axis) {
-                chart.data.addColumn('number',axis.name);
+                chart.data.addColumn('number', axis.name);
             }
             var rows = []; // Rows is an array of tuples [col1, col2, col3 ... colN];
             for (var element of page.elements) {
                 var entry = [element.id];
-                for (var i=0; i<page.elements[0].axis.length; i++) {
-                    var mean =0;
+                for (var i = 0; i < page.elements[0].axis.length; i++) {
+                    var mean = 0;
                     if (i < element.axis.length) {
                         var axis = element.axis[i];
                         mean = arrayMean(axis.values);
@@ -522,20 +544,20 @@
             }
             chart.data.addRows(rows);
             chart.options = {
-                'title':'Mean of page: '+page.id,
-                'width':800,
-                'height':700
-            }
-            // Draw the chart
+                    'title': 'Mean of page: ' + page.id,
+                    'width': 800,
+                    'height': 700
+                }
+                // Draw the chart
             chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
-            chart.chart.draw(chart.data,chart.options);
+            chart.chart.draw(chart.data, chart.options);
             chart.buildTable();
             chart.writeLatex();
             this.charts.push(chart);
         }
     }
-    
-    this.drawElementHistogram = function() {
+
+    this.drawElementHistogram = function () {
         // First we must get the value data
         if (this.valueData == null) {
             console.log("Error - Data not loaded");
@@ -545,18 +567,17 @@
         for (var page of this.valueData.pages) {
             for (var element of page.elements) {
                 // Build the chart object
-                var chart = new this.chartObject("histogram-element-"+element.id);
+                var chart = new this.chartObject("histogram-element-" + element.id);
                 document.getElementById("test-pages").appendChild(chart.root);
-                chart.data.addColumn('string','index');
+                chart.data.addColumn('string', 'index');
                 var histograms = [];
                 for (var axis of element.axis) {
-                    chart.data.addColumn('number',axis.name);
-                    histograms.push(arrayHistogram(axis.values,0.125,0.0,1.0));
+                    chart.data.addColumn('number', axis.name);
+                    histograms.push(arrayHistogram(axis.values, 0.125, 0.0, 1.0));
                 }
                 for (var axis of element.axis) {
-                    for (var i=0; i<histograms[0].length; i++)
-                    {
-                        var entry = [""+histograms[0][i].lt.toPrecision(2)+"-"+histograms[0][i].rt.toPrecision(3)]
+                    for (var i = 0; i < histograms[0].length; i++) {
+                        var entry = ["" + histograms[0][i].lt.toPrecision(2) + "-" + histograms[0][i].rt.toPrecision(3)]
                         for (var histogram of histograms) {
                             entry.push(histogram[i].count);
                         }
@@ -564,14 +585,16 @@
                     }
                 }
                 chart.options = {
-                    'title':'Histogram of element: '+element.id,
-                    'width':800,
-                    'height':700,
-                    'bar':{'groupWidth': '100%'}
-                }
-                // Draw the chart
+                        'title': 'Histogram of element: ' + element.id,
+                        'width': 800,
+                        'height': 700,
+                        'bar': {
+                            'groupWidth': '100%'
+                        }
+                    }
+                    // Draw the chart
                 chart.chart = new google.visualization.ColumnChart(chart.chartDOM);
-                chart.chart.draw(chart.data,chart.options);
+                chart.chart.draw(chart.data, chart.options);
                 chart.buildTable();
                 chart.writeLatex();
                 this.charts.push(chart);
@@ -582,49 +605,51 @@
 
 function Data() {
     // This holds the link between the server side calculations and the client side visualisation of the data
-    
+
     // Dynamically generate the test filtering / page filterting tools
     var self = this;
     // Collect the test types and counts
     this.testSavedDiv = document.getElementById("test-saved");
     this.testSaves = null;
     this.selectURL = null;
-    
+
     this.specification = new Specification();
-    get("../xml/test-schema.xsd").then(function(response){
+    get("../xml/test-schema.xsd").then(function (response) {
         var parse = new DOMParser();
-        self.specification.schema = parse.parseFromString(response,'text/xml');
-    },function(error){
+        self.specification.schema = parse.parseFromString(response, 'text/xml');
+    }, function (error) {
         console.log("ERROR: Could not get Test Schema");
     });
-    this.update = function(url) {
+    this.update = function (url) {
         var self = this;
     }
-    
-    this.updateData = function(req_str) {
+
+    this.updateData = function (req_str) {
         // Now go get that data
-        get(req_str).then(function(response){
+        get(req_str).then(function (response) {
             // Returns the data
             chartContext.valueData = JSON.parse(response);
-        },function(error){console.error(error);});
+        }, function (error) {
+            console.error(error);
+        });
     }
 }
 
-var interfaceContext = new function() {
+var interfaceContext = new function () {
     // This creates the interface for the user to connect with the dynamic back-end to retrieve data
     this.rootDOM = document.createElement("div");
     this.getDataButton = {
         button: document.createElement("button"),
         parent: this,
-        handleEvent: function(event) {
+        handleEvent: function (event) {
             // Get the list of files:
-            var req_str = "../php/get_filtered_score.php"+this.parent.getFilterString();
+            var req_str = "../php/get_filtered_score.php" + this.parent.getFilterString();
             testData.updateData(req_str);
         }
     }
     this.getDataButton.button.textContent = "Get Filtered Data";
-    this.getDataButton.button.addEventListener("click",this.getDataButton);
-    
+    this.getDataButton.button.addEventListener("click", this.getDataButton);
+
     this.getRawScoreData = {
         root: document.createElement("div"),
         csvDOM: document.createElement("button"),
@@ -633,36 +658,42 @@
         presentDOM: document.createElement("div"),
         parent: this,
         XHR: new XMLHttpRequest(),
-        handleEvent: function(event) {
+        handleEvent: function (event) {
             this.presentDOM.innerHTML = null;
-            var url = "../php/get_filtered_score.php"+this.parent.getFilterString();
-            this.XHR.open("GET",url+"&format="+event.currentTarget.textContent,true);
-            switch(event.currentTarget.textContent) {
+            var url = "../php/get_filtered_score.php" + this.parent.getFilterString();
+            this.XHR.open("GET", url + "&format=" + event.currentTarget.textContent, true);
+            switch (event.currentTarget.textContent) {
                 case "CSV":
-                    this.XHR.onload = function() {
+                    this.XHR.onload = function () {
                         var file = [this.response];
-                        var bb = new Blob(file,{type: 'text/csv'});
-                        this.parent.presentDOM.appendChild( this.parent.generateLink(bb,"scores.csv") );
+                        var bb = new Blob(file, {
+                            type: 'text/csv'
+                        });
+                        this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.csv"));
                     }
                     break;
                 case "JSON":
-                    this.XHR.onload = function() {
+                    this.XHR.onload = function () {
                         var file = [this.response];
-                        var bb = new Blob(file,{type: 'application/json'});
-                        this.parent.presentDOM.appendChild( this.parent.generateLink(bb,"scores.json") );
+                        var bb = new Blob(file, {
+                            type: 'application/json'
+                        });
+                        this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.json"));
                     }
                     break;
                 case "XML":
-                    this.XHR.onload = function() {
+                    this.XHR.onload = function () {
                         var file = [this.response];
-                        var bb = new Blob(file,{type: 'text/xml'});
-                        this.parent.presentDOM.appendChild( this.parent.generateLink(bb,"scores.xml") );
+                        var bb = new Blob(file, {
+                            type: 'text/xml'
+                        });
+                        this.parent.presentDOM.appendChild(this.parent.generateLink(bb, "scores.xml"));
                     }
                     break;
             }
             this.XHR.send();
         },
-        generateLink: function(blob,filename) {
+        generateLink: function (blob, filename) {
             var dnlk = window.URL.createObjectURL(blob);
             var a = document.createElement("a");
             a.hidden = '';
@@ -672,28 +703,28 @@
             return a;
         }
     }
-    
+
     this.getRawScoreData.root.appendChild(this.getRawScoreData.csvDOM);
     this.getRawScoreData.root.appendChild(this.getRawScoreData.jsonDOM);
     this.getRawScoreData.root.appendChild(this.getRawScoreData.xmlDOM);
     this.getRawScoreData.root.appendChild(this.getRawScoreData.presentDOM);
     this.getRawScoreData.XHR.parent = this.getRawScoreData;
     this.getRawScoreData.csvDOM.textContent = 'CSV';
-    this.getRawScoreData.csvDOM.addEventListener('click',this.getRawScoreData);
+    this.getRawScoreData.csvDOM.addEventListener('click', this.getRawScoreData);
     this.getRawScoreData.jsonDOM.textContent = 'JSON';
-    this.getRawScoreData.jsonDOM.addEventListener('click',this.getRawScoreData);
+    this.getRawScoreData.jsonDOM.addEventListener('click', this.getRawScoreData);
     this.getRawScoreData.xmlDOM.textContent = 'XML';
-    this.getRawScoreData.xmlDOM.addEventListener('click',this.getRawScoreData);
-    
+    this.getRawScoreData.xmlDOM.addEventListener('click', this.getRawScoreData);
+
     this.testSaves = {
         json: null,
         selectedURL: null,
         inputs: [],
         parent: this
     };
-    this.init = function() {
+    this.init = function () {
         var self = this;
-        get('../php/get_tests.php?format=JSON').then(function(response){
+        get('../php/get_tests.php?format=JSON').then(function (response) {
             document.getElementById("test-saved").innerHTML = null;
             var table = document.createElement("table");
             table.innerHTML = "<tr><td>Test Filename</td><td>Count</td><td>Include</td></tr>";
@@ -710,50 +741,52 @@
                 var obj = {
                     root: document.createElement("input"),
                     parent: self.testSaves,
-                    handleEvent: function(event) {
+                    handleEvent: function (event) {
                         this.parent.selectedURL = event.currentTarget.getAttribute("source");
                         var self = this;
-                        get(this.parent.selectedURL).then(function(response){
+                        get(this.parent.selectedURL).then(function (response) {
                             var parse = new DOMParser();
-                            testData.specification.decode(parse.parseFromString(response,'text/xml'));
+                            testData.specification.decode(parse.parseFromString(response, 'text/xml'));
                             self.parent.parent.generateFilters(testData.specification);
                             self.parent.parent.getFileCount();
                             return true;
-                        },function(error){
-                            console.log("ERROR: Could not get"+url);
+                        }, function (error) {
+                            console.log("ERROR: Could not get" + url);
                             return false;
                         });
                     }
                 }
                 obj.root.type = "radio";
                 obj.root.name = "test-include";
-                obj.root.setAttribute("source",test.testName);
-                obj.root.addEventListener("change",obj);
+                obj.root.setAttribute("source", test.testName);
+                obj.root.addEventListener("change", obj);
                 tableRowInclude.appendChild(obj.root);
                 tableRow.appendChild(tableRowInclude);
                 table.appendChild(tableRow);
                 self.testSaves.inputs.push(obj);
             }
             document.getElementById("test-saved").appendChild(table);
-        },function(error){console.error(error);});
+        }, function (error) {
+            console.error(error);
+        });
     }
-    
+
     this.filterDOM = document.createElement("div");
     this.filterDOM.innerHTML = "<p>PreTest Filters</p><div id='filter-count'></div>";
     this.filterObjects = [];
-    this.generateFilters = function(specification) {
+    this.generateFilters = function (specification) {
         // Filters are based on the pre and post global surverys
-        var FilterObject = function(parent,specification) {
+        var FilterObject = function (parent, specification) {
             this.parent = parent;
             this.specification = specification;
             this.rootDOM = document.createElement("div");
-            this.rootDOM.innerHTML = "<span>ID: "+specification.id+", Type: "+specification.type+"</span>";
+            this.rootDOM.innerHTML = "<span>ID: " + specification.id + ", Type: " + specification.type + "</span>";
             this.rootDOM.className = "filter-entry";
-            this.handleEvent = function(event) {
-                switch(this.specification.type) {
+            this.handleEvent = function (event) {
+                switch (this.specification.type) {
                     case "number":
                         var name = event.currentTarget.name;
-                        eval("this."+name+" = event.currentTarget.value");
+                        eval("this." + name + " = event.currentTarget.value");
                         break;
                     case "checkbox":
                         break;
@@ -762,29 +795,29 @@
                 }
                 this.parent.getFileCount();
             }
-            this.getFilterPairs = function() {
+            this.getFilterPairs = function () {
                 var pairs = [];
-                switch(this.specification.type) {
+                switch (this.specification.type) {
                     case "number":
                         if (this.min != "") {
-                            pairs.push([specification.id+"-min",this.min]);
+                            pairs.push([specification.id + "-min", this.min]);
                         }
                         if (this.max != "") {
-                            pairs.push([specification.id+"-max",this.max]);
+                            pairs.push([specification.id + "-max", this.max]);
                         }
                         break;
                     case "radio":
                     case "checkbox":
-                        for (var i=0; i<this.options.length; i++) {
+                        for (var i = 0; i < this.options.length; i++) {
                             if (!this.options[i].checked) {
-                                pairs.push([specification.id+"-exclude-"+i,specification.options[i].name]);
+                                pairs.push([specification.id + "-exclude-" + i, specification.options[i].name]);
                             }
                         }
                         break;
                 }
                 return pairs;
             }
-            switch(specification.type) {
+            switch (specification.type) {
                 case "number":
                     // Number can be ranged by min/max levels
                     this.min = "";
@@ -792,18 +825,18 @@
                     this.minDOM = document.createElement("input");
                     this.minDOM.type = "number";
                     this.minDOM.name = "min";
-                    this.minDOM.addEventListener("change",this);
+                    this.minDOM.addEventListener("change", this);
                     this.minDOMText = document.createElement("span");
                     this.minDOMText.textContent = "Minimum: ";
                     var pairHolder = document.createElement("div");
                     pairHolder.appendChild(this.minDOMText);
                     pairHolder.appendChild(this.minDOM);
                     this.rootDOM.appendChild(pairHolder);
-                    
+
                     this.maxDOM = document.createElement("input");
                     this.maxDOM.type = "number";
                     this.maxDOM.name = "max";
-                    this.maxDOM.addEventListener("change",this);
+                    this.maxDOM.addEventListener("change", this);
                     this.maxDOMText = document.createElement("span");
                     this.maxDOMText.textContent = "Maximum: ";
                     var pairHolder = document.createElement("div");
@@ -814,16 +847,16 @@
                 case "radio":
                 case "checkbox":
                     this.options = [];
-                    for (var i=0; i<specification.options.length; i++) {
+                    for (var i = 0; i < specification.options.length; i++) {
                         var option = specification.options[i];
                         var pairHolder = document.createElement("div");
                         var text = document.createElement("span");
                         text.textContent = option.text;
                         var check = document.createElement("input");
                         check.type = "checkbox";
-                        check.setAttribute("option-index",i);
+                        check.setAttribute("option-index", i);
                         check.checked = true;
-                        check.addEventListener("click",this);
+                        check.addEventListener("click", this);
                         this.options.push(check);
                         pairHolder.appendChild(text);
                         pairHolder.appendChild(check);
@@ -835,18 +868,18 @@
             }
         }
         var options = [];
-        if(specification.preTest) {
+        if (specification.preTest) {
             options = options.concat(specification.preTest.options);
         }
         if (specification.postTest) {
             options = options.concat(specification.postTest.options);
         }
         for (var survey_entry of options) {
-            switch(survey_entry.type) {
+            switch (survey_entry.type) {
                 case "number":
                 case "radio":
                 case "checkbox":
-                    var node = new FilterObject(this,survey_entry);
+                    var node = new FilterObject(this, survey_entry);
                     this.filterObjects.push(node);
                     this.filterDOM.appendChild(node.rootDOM);
                     break;
@@ -858,41 +891,41 @@
         document.getElementById("test-saved").appendChild(this.getDataButton.button);
         document.getElementById("test-saved").appendChild(this.getRawScoreData.root);
     }
-    this.getFilterString = function() {
+    this.getFilterString = function () {
         var pairs = [];
         for (var obj of this.filterObjects) {
             pairs = pairs.concat(obj.getFilterPairs());
         }
-        var req_str = "?url="+this.testSaves.selectedURL;
+        var req_str = "?url=" + this.testSaves.selectedURL;
         var index = 0;
-        while(pairs[index] != undefined) {
+        while (pairs[index] != undefined) {
             req_str += '&';
-            req_str += pairs[index][0]+"="+pairs[index][1];
+            req_str += pairs[index][0] + "=" + pairs[index][1];
             index++;
         }
         return req_str;
     }
-    this.getFilteredUrlArray = function() {
-        var req_str = "../php/get_filtered_count.php"+this.getFilterString();
-        return get(req_str).then(function(response){
+    this.getFilteredUrlArray = function () {
+        var req_str = "../php/get_filtered_count.php" + this.getFilterString();
+        return get(req_str).then(function (response) {
             var urls = JSON.parse(response);
             return urls.urls;
-        },function(error){
+        }, function (error) {
             console.error(error);
         });
     }
-    this.getFileCount = function() {
+    this.getFileCount = function () {
         // First we must get the filter pairs
-        this.getFilteredUrlArray().then(function(response){
-            var str = "Filtered to "+response.length+" file";
+        this.getFilteredUrlArray().then(function (response) {
+            var str = "Filtered to " + response.length + " file";
             if (response.length != 1) {
                 str += "s.";
             } else {
                 str += ".";
             }
             document.getElementById("filter-count").textContent = str;
-        },function(error){});
+        }, function (error) {});
     }
-    
+
     this.init();
-}
\ No newline at end of file
+}
--- a/analysis/index.html	Mon Nov 14 12:11:38 2016 +0000
+++ b/analysis/index.html	Mon Nov 14 14:17:03 2016 +0000
@@ -1,29 +1,32 @@
 <html lang="en">
-    <head>
-        <meta charset="utf-8" />
-        <link rel='stylesheet' href="analysis.css" type="text/css"/>
-        <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
-        <script type="text/javascript" src="analysis.js"></script>
-        <script type="text/javascript" src="../js/specification.js"></script>
-    </head>
-    <body>
-        <h1>Web Audio Evaluation Toolbox: Analysis</h1>
-        <div id="test-saved"></div>
-        <button onclick="chartContext.clear();">Clear Charts</button>
-        <div id="test-charts">
-            <p>Charts per test</p>
-            <button onclick="chartContext.drawTestMean();">Means</button>
-            <button onclick="chartContext.drawTestBoxplot();">Boxplot</button>
-        </div>
-        <div id="page-charts">
-            <p>Charts per test page</p>
-            <button onclick="chartContext.drawPageMean();">Means</button>
-        </div>
-        <div id="element-charts">
-            <p>Charts per element</p>
-            <button onclick="chartContext.drawElementHistogram();">Histogram</button>
-        </div>
-        
-        <div id="test-pages"></div>
-    </body>
-</html>
\ No newline at end of file
+
+<head>
+    <meta charset="utf-8" />
+    <link rel='stylesheet' href="analysis.css" type="text/css" />
+    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
+    <script type="text/javascript" src="analysis.js"></script>
+    <script type="text/javascript" src="../js/specification.js"></script>
+</head>
+
+<body>
+    <h1>Web Audio Evaluation Toolbox: Analysis</h1>
+    <div id="test-saved"></div>
+    <button onclick="chartContext.clear();">Clear Charts</button>
+    <div id="test-charts">
+        <p>Charts per test</p>
+        <button onclick="chartContext.drawTestMean();">Means</button>
+        <button onclick="chartContext.drawTestBoxplot();">Boxplot</button>
+    </div>
+    <div id="page-charts">
+        <p>Charts per test page</p>
+        <button onclick="chartContext.drawPageMean();">Means</button>
+    </div>
+    <div id="element-charts">
+        <p>Charts per element</p>
+        <button onclick="chartContext.drawElementHistogram();">Histogram</button>
+    </div>
+
+    <div id="test-pages"></div>
+</body>
+
+</html>
--- a/css/core.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/css/core.css	Mon Nov 14 14:17:03 2016 +0000
@@ -3,60 +3,53 @@
  */
 
 div.title {
-	width: 100%;
-	height: 50px;
-	margin-bottom: 10px;
-	font-size: 2em;
+    width: 100%;
+    height: 50px;
+    margin-bottom: 10px;
+    font-size: 2em;
 }
-
 div.indicator-box {
-	position: absolute;
-	left: 150px;
-	top: 10px;
-	width: 300px;
-	height: 60px;
-	padding: 20px;
-	border-radius: 10px;
-	background-color: rgb(100,200,200);
+    position: absolute;
+    left: 150px;
+    top: 10px;
+    width: 300px;
+    height: 60px;
+    padding: 20px;
+    border-radius: 10px;
+    background-color: rgb(100, 200, 200);
 }
-
 div.comment-div {
-	border:1px solid #444444;
-	max-width: 600px;
-	min-width: 400px;
-	float: left;
-	margin: 5px 10px 5px 5px;
-	height: 90px;
+    border: 1px solid #444444;
+    max-width: 600px;
+    min-width: 400px;
+    float: left;
+    margin: 5px 10px 5px 5px;
+    height: 90px;
     border-radius: 10px;
 }
-
 div.comment-div span {
-	margin-left: 15px;
+    margin-left: 15px;
 }
-
 div.popupHolder {
-	width: 500px;
-	min-height: 250px;
-	max-height: 400px;
-	background-color: #fff;
-	border-radius: 10px;
-	box-shadow: 0px 0px 50px #000;
-	z-index: 10;
-	position: fixed;
+    width: 500px;
+    min-height: 250px;
+    max-height: 400px;
+    background-color: #fff;
+    border-radius: 10px;
+    box-shadow: 0px 0px 50px #000;
+    z-index: 10;
+    position: fixed;
 }
-
 div#popupContent {
     margin-top: 20px;
     margin-bottom: 35px;
     overflow: auto;
 }
-
 div#popupContent iframe {
     width: 100%;
     border: 0px none;
     height: 290px;
 }
-
 div#popupTitleHolder {
     width: inherit;
     min-height: 25px;
@@ -66,11 +59,9 @@
     padding: 8px;
     text-align: center;
 }
-
 #popupTitle {
     white-space: pre-line;
 }
-
 div#popupResponse {
     width: inherit;
     min-height: 50px;
@@ -78,20 +69,18 @@
     overflow: auto;
     position: relative;
 }
-
 button.popupButton {
-	/* Button for popup window
+    /* Button for popup window
 	 */
-	width: 50px;
-	height: 25px;
-	position: absolute;
-	border-radius: 5px;
-	border: #444;
-	border-width: 1px;
-	border-style: solid;
-	background-color: #fff;
+    width: 50px;
+    height: 25px;
+    position: absolute;
+    border-radius: 5px;
+    border: #444;
+    border-width: 1px;
+    border-style: solid;
+    background-color: #fff;
 }
-
 div.popup-option-checbox {
     /* Popup window checkbox */
     padding: 5px;
@@ -99,46 +88,38 @@
     width: -moz-fit-content;
     width: -webkit-fit-content;
 }
-
-div.popup-option-checbox input{
+div.popup-option-checbox input {
     /* Popup window checkbox */
     margin-right: 15px;
 }
-
 table.popup-option-list {
     margin: auto;
 }
-
 table.popup-option-list tr {
     padding: 5px;
 }
-
 table.popup-option-list tr td {
     padding: 5px;
 }
-
 button#popup-proceed {
     bottom: 10px;
     right: 10px;
 }
-
 button#popup-previous {
     bottom: 10px;
     left: 10px;
 }
-
 div.testHalt {
-	/* Specify any colouring during the test halt for pre/post questions */
-	background-color: rgba(0,0,0,0.5);
-	/* Don't mess with this bit */
-	z-index: 9;
-	width: 100%;
-	height: 100%;
-	position: fixed;
-	left: 0px;
-	top: 0px;
+    /* Specify any colouring during the test halt for pre/post questions */
+    background-color: rgba(0, 0, 0, 0.5);
+    /* Don't mess with this bit */
+    z-index: 9;
+    width: 100%;
+    height: 100%;
+    position: fixed;
+    left: 0px;
+    top: 0px;
 }
-
 div#lightbox-root {
     visibility: hidden;
     z-index: 20;
@@ -146,80 +127,69 @@
     min-height: 50px;
     max-height: 250px;
 }
-
 div.lightbox-error {
     margin: 25px;
     margin-bottom: 50px;
     padding: 5px;
     border-radius: 5px;
-    background-color: rgb(255,220,220);
-    border: 2px rgb(200,0,0) solid;
+    background-color: rgb(255, 220, 220);
+    border: 2px rgb(200, 0, 0) solid;
 }
-
 div.lightbox-warning {
     margin: 25px;
     margin-bottom: 50px;
     padding: 5px;
     border-radius: 5px;
-    background-color: rgb(255,255,220);
-    border: 2px rgb(255,250,0) solid;
+    background-color: rgb(255, 255, 220);
+    border: 2px rgb(255, 250, 0) solid;
 }
-
 div.lightbox-message {
     margin: 25px;
     margin-bottom: 50px;
     padding: 5px;
     border-radius: 5px;
-    background-color: rgb(200,220,255);
-    border: 2px rgb(50,100,250) solid;
+    background-color: rgb(200, 220, 255);
+    border: 2px rgb(50, 100, 250) solid;
 }
-
 div#lightbox-blanker {
     visibility: hidden;
     z-index: 19;
 }
-
 button.outside-reference {
-	width:120px;
-	height:20px;
-	margin-bottom:5px;
-	position: absolute;
+    width: 120px;
+    height: 20px;
+    margin-bottom: 5px;
+    position: absolute;
 }
-
 textarea.trackComment {
-	max-width: 594px;
-	min-width: 350px;
-	max-height: 60px;
+    max-width: 594px;
+    min-width: 350px;
+    max-height: 60px;
     resize: none;
 }
-
 div.playhead {
-	width: 500px;
-	height: 50px;
-	background-color: #eee;
-	border-radius: 10px;
-	padding: 10px;
+    width: 500px;
+    height: 50px;
+    background-color: #eee;
+    border-radius: 10px;
+    padding: 10px;
 }
-
 div.playhead-scrub-track {
-	width: 100%;
-	height: 10px;
-	border-style: solid;
-	border-width: 1px;
+    width: 100%;
+    height: 10px;
+    border-style: solid;
+    border-width: 1px;
 }
-
 div#playhead-scrubber {
-	width: 10px;
-	height: 10px;
-	position: relative;
-	background-color: #000;
+    width: 10px;
+    height: 10px;
+    position: relative;
+    background-color: #000;
 }
-
 div.master-volume-holder-inline {
     width: 100%;
     padding: 5px;
 }
-
 div.master-volume-holder-float {
     position: absolute;
     top: 20px;
@@ -227,15 +197,13 @@
     width: 250px%;
     padding: 5px;
 }
-
 div#master-volume-root {
-    margin:auto;
+    margin: auto;
     border: black 1px solid;
     border-radius: 5px;
     width: 250px;
     height: 40px;
 }
-
 input#master-volume-control {
     width: 200px;
     height: 25px;
@@ -243,14 +211,12 @@
     margin: 0px;
     padding: 0px;
 }
-
 span#master-volume-feedback {
     width: 45px;
     height: 25px;
     margin-left: 5px;
     float: left;
 }
-
 div.error-colour {
     background-color: #FF8F8F;
 }
@@ -258,13 +224,11 @@
     background-color: #FF8F8F;
     color: black;
 }
-
 div.calibration-holder {
     text-align: center;
     align-content: center;
     height: auto;
 }
-
 div.calibration-slider {
     width: 50px;
     margin: 2px;
@@ -272,11 +236,11 @@
     align-content: center;
     float: left;
 }
-
-div.calibration-slider input[type=range][orient=vertical]
-{
-    writing-mode: bt-lr; /* IE */
-    -webkit-appearance: slider-vertical; /* WebKit */
+div.calibration-slider input[type=range][orient=vertical] {
+    writing-mode: bt-lr;
+    /* IE */
+    -webkit-appearance: slider-vertical;
+    /* WebKit */
     width: 8px;
     padding: 0 5px;
     height: 290px;
--- a/index.html	Mon Nov 14 12:11:38 2016 +0000
+++ b/index.html	Mon Nov 14 14:17:03 2016 +0000
@@ -1,55 +1,57 @@
 <!DOCTYPE html>
 <html lang="en">
-    <head>
-		<meta http-equiv="content-type" content="text/html; charset=utf-8">
 
+<head>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
-		<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
+
+    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
 		Remove this if you use the .htaccess -->
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 
-		<title>Web Audio Evaluation Tool</title>
-		<meta name="description" content="" />
-		<meta name="author" content="" />
-		
-		<!-- Load up the default core JS and CSS files-->
-		<link rel='stylesheet' type='text/css' href='css/core.css'>
-		<!-- Use jQuery hosted from Google CDN -->
-		<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
-		<script type="text/javascript" src="js/jquery-2.1.4.js"></script>
-        <script type="text/javascript" src="js/loader.js"></script>
-	</head>
+    <title>Web Audio Evaluation Tool</title>
+    <meta name="description" content="" />
+    <meta name="author" content="" />
 
-	<body>
-		<div id='topLevelBody'>
-			<h1>Web Audio Evaluation Tool</h1>
-			<h2>Start menu </h2>
-			<ul>
-				<li><a href="test.html?url=tests/examples/project.xml" target="_blank">APE interface test example</a></li>
-				<li><a href="test.html?url=tests/examples/mushra_example.xml" target="_blank">MUSHRA interface test example</a></li>
-				<li><a href="test.html?url=tests/examples/AB_example.xml" target="_blank">AB interface test example</a></li>
-				<li><a href="test.html?url=tests/examples/horizontal_example.xml" target="_blank">Horizontal interface test example</a></li>
-				<li><a href="test.html?url=tests/examples/radio_example.xml" target="_blank">Radio interface test example</a></li>
-				<li><a href="test_create.html" target="_blank">Test creator</a></li>
-				<li><a href="analyse.html" target="_blank">Analysis and diagnostics of results</a></li>
-			</ul>
-			<br>
-			<ul>
-				<li><a href="LICENSE.txt" target="_blank">License</a></li>
-				<li><a href="CITING.txt" target="_blank">Citing</a></li>
-				<li><a href="docs/Instructions/Instructions.pdf" target="_blank">Instructions</a></li>
-			</ul>
-		</div>
-        <div id="popupHolder" class="popupHolder" style="visibility: hidden">
-            <div id="popupContent">
-                <div id="popupTitleHolder">
-                    <span id="popupTitle"></span>
-                </div>
-                <div id="popupResponse"></div>
+    <!-- Load up the default core JS and CSS files-->
+    <link rel='stylesheet' type='text/css' href='css/core.css'>
+    <!-- Use jQuery hosted from Google CDN -->
+    <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
+    <script type="text/javascript" src="js/jquery-2.1.4.js"></script>
+    <script type="text/javascript" src="js/loader.js"></script>
+</head>
+
+<body>
+    <div id='topLevelBody'>
+        <h1>Web Audio Evaluation Tool</h1>
+        <h2>Start menu </h2>
+        <ul>
+            <li><a href="test.html?url=tests/examples/project.xml" target="_blank">APE interface test example</a></li>
+            <li><a href="test.html?url=tests/examples/mushra_example.xml" target="_blank">MUSHRA interface test example</a></li>
+            <li><a href="test.html?url=tests/examples/AB_example.xml" target="_blank">AB interface test example</a></li>
+            <li><a href="test.html?url=tests/examples/horizontal_example.xml" target="_blank">Horizontal interface test example</a></li>
+            <li><a href="test.html?url=tests/examples/radio_example.xml" target="_blank">Radio interface test example</a></li>
+            <li><a href="test_create.html" target="_blank">Test creator</a></li>
+            <li><a href="analyse.html" target="_blank">Analysis and diagnostics of results</a></li>
+        </ul>
+        <br>
+        <ul>
+            <li><a href="LICENSE.txt" target="_blank">License</a></li>
+            <li><a href="CITING.txt" target="_blank">Citing</a></li>
+            <li><a href="docs/Instructions/Instructions.pdf" target="_blank">Instructions</a></li>
+        </ul>
+    </div>
+    <div id="popupHolder" class="popupHolder" style="visibility: hidden">
+        <div id="popupContent">
+            <div id="popupTitleHolder">
+                <span id="popupTitle"></span>
             </div>
-            <button id="popup-proceed" class="popupButton">Next</button>
-            <button id="popup-previous" class="popupButton">Back</button>
+            <div id="popupResponse"></div>
         </div>
-        <div class="testHalt" style="visibility: hidden"></div>
-	</body>
+        <button id="popup-proceed" class="popupButton">Next</button>
+        <button id="popup-previous" class="popupButton">Back</button>
+    </div>
+    <div class="testHalt" style="visibility: hidden"></div>
+</body>
+
 </html>
--- a/interfaces/AB.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/AB.css	Mon Nov 14 14:17:03 2016 +0000
@@ -1,95 +1,79 @@
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #fff
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #fff
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin: 10px 0px;
+    width: auto;
+    height: 20px;
+    margin: 10px 0px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 button.big-button {
-	width: 250px;
-	height: 40px;
-	font-size: 1.2em;
+    width: 250px;
+    height: 40px;
+    font-size: 1.2em;
 }
-
 div.interface-buttons {
     height: 40px;
 }
-
 div#outside-reference-holder {
     display: flex;
     align-content: center;
     justify-content: center;
     margin-bottom: 5px;
 }
-
 button.outside-reference {
     height: 40px;
     position: inherit;
     margin: 0px 5px;
 }
-
 div.comparator-holder {
-	width: 260px;
-	height: 300px;
-	border:  black 1px solid;
+    width: 260px;
+    height: 300px;
+    border: black 1px solid;
     float: left;
-	padding-top: 5px;
+    padding-top: 5px;
     margin: 25px;
 }
-
 div.comparator-selector {
-	width: 248px;
-	height: 250px;
-	border: black 1px solid;
-	position: relative;
-	background-color: #FF0000;
+    width: 248px;
+    height: 250px;
+    border: black 1px solid;
+    position: relative;
+    background-color: #FF0000;
     border-radius: 20px;
 }
-
 div.disabled {
-	background-color: #AAA;
+    background-color: #AAA;
 }
-
 div.selected {
-	background-color: #008000;
+    background-color: #008000;
 }
-
 div.comparator-selector span {
-	font-size: 4em;
+    font-size: 4em;
 }
-
 button.comparator-button {
-	width: 250px;
-	height: 38px;
-	position: relative;
-	margin-top: 5px;
+    width: 250px;
+    height: 38px;
+    position: relative;
+    margin-top: 5px;
 }
-
 div.playhead {
     margin: 5px;
 }
-
 div#page-count {
     float: left;
     margin: 0px 5px;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
     left: 120px;
-}
\ No newline at end of file
+}
--- a/interfaces/AB.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/AB.js	Mon Nov 14 14:17:03 2016 +0000
@@ -2,15 +2,15 @@
 loadInterface();
 
 function loadInterface() {
-	// Get the dimensions of the screen available to the page
-	var width = window.innerWidth;
-	var height = window.innerHeight;
-	interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-	
-	// Custom comparator Object
-	Interface.prototype.comparator = null;
-    
-    Interface.prototype.checkScaleRange = function(min, max) {
+    // Get the dimensions of the screen available to the page
+    var width = window.innerWidth;
+    var height = window.innerHeight;
+    interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
+
+    // Custom comparator Object
+    Interface.prototype.comparator = null;
+
+    Interface.prototype.checkScaleRange = function (min, max) {
         var page = testState.getCurrentTestPage();
         var audioObjects = audioEngineContext.audioObjects;
         var state = true;
@@ -19,166 +19,170 @@
         var maxRanking = -Infinity;
         for (var ao of audioObjects) {
             var rank = ao.interfaceDOM.getValue();
-            if (rank < minRanking) {minRanking = rank;}
-            if (rank > maxRanking) {maxRanking = rank;}
+            if (rank < minRanking) {
+                minRanking = rank;
+            }
+            if (rank > maxRanking) {
+                maxRanking = rank;
+            }
         }
-        if (maxRanking*100 < max) {
+        if (maxRanking * 100 < max) {
             str += "At least one fragment must be selected."
             state = false;
         }
         if (!state) {
             console.log(str);
             this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message",str);
+            interfaceContext.lightbox.post("Message", str);
         }
         return state;
     }
-	
-	// The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	testContent.id = 'testContent';
-	
-	// Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
+
+    // The injection point into the HTML page
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+    testContent.id = 'testContent';
+
+    // Create the top div for the Title element
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
     titleSpan.id = "test-title";
-	
-	// Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-	
-	var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle";
-	pagetitle.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	interfaceButtons.style.height = '25px';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	playback.style.float = 'left';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+
+    // Set title to that defined in XML, else set to default
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
+    var pagetitle = document.createElement('div');
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle";
+    pagetitle.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+    interfaceButtons.style.height = '25px';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    playback.style.float = 'left';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-    
+        }
+    };
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
     // Create outside reference holder
     var outsideRef = document.createElement("div");
     outsideRef.id = "outside-reference-holder";
-	
-	// Construct the AB Boxes
-	var boxes = document.createElement('div');
-	boxes.align = "center";
-	boxes.id = "box-holders";
+
+    // Construct the AB Boxes
+    var boxes = document.createElement('div');
+    boxes.align = "center";
+    boxes.id = "box-holders";
     boxes.style.float = "left";
-	
-	var submit = document.createElement('button');
-	submit.id = "submit";
-	submit.onclick = buttonSubmitClick;
-	submit.className = "big-button";
-	submit.textContent = "submit";
-	submit.style.position = "relative";
-	submit.style.left = (window.innerWidth-250)/2 + 'px';
-		
-	feedbackHolder.appendChild(boxes);
-    
+
+    var submit = document.createElement('button');
+    submit.id = "submit";
+    submit.onclick = buttonSubmitClick;
+    submit.className = "big-button";
+    submit.textContent = "submit";
+    submit.style.position = "relative";
+    submit.style.left = (window.innerWidth - 250) / 2 + 'px';
+
+    feedbackHolder.appendChild(boxes);
+
     // Create holder for comment boxes
     var comments = document.createElement("div");
     comments.id = "comment-box-holder";
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(pagetitle);
-	testContent.appendChild(interfaceButtons);
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(pagetitle);
+    testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
-	testContent.appendChild(feedbackHolder);
-	testContent.appendChild(submit);
+    testContent.appendChild(feedbackHolder);
+    testContent.appendChild(submit);
     testContent.appendChild(comments);
-	interfaceContext.insertPoint.appendChild(testContent);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
 }
 
-function loadTest(audioHolderObject)
-{
-	var feedbackHolder = document.getElementById('feedbackHolder');
-	var interfaceObj = audioHolderObject.interfaces;
-	if (interfaceObj.length > 1)
-	{
-		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
-	}
-	interfaceObj = interfaceObj[0];
-    
+function loadTest(audioHolderObject) {
+    var feedbackHolder = document.getElementById('feedbackHolder');
+    var interfaceObj = audioHolderObject.interfaces;
+    if (interfaceObj.length > 1) {
+        console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+    }
+    interfaceObj = interfaceObj[0];
+
     var commentHolder = document.getElementById('comment-box-holder');
     commentHolder.innerHTML = "";
-    
+
     // Delete outside reference
-	var outsideReferenceHolder = document.getElementById("outside-reference-holder");
+    var outsideReferenceHolder = document.getElementById("outside-reference-holder");
     outsideReferenceHolder.innerHTML = "";
-    
+
     // Set the page title
     if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) {
         document.getElementById("test-title").textContent = audioHolderObject.title
     }
-	
-	if(interfaceObj.title != null)
-	{
-		document.getElementById("pageTitle").textContent = interfaceObj.title;
-	}
-    
+
+    if (interfaceObj.title != null) {
+        document.getElementById("pageTitle").textContent = interfaceObj.title;
+    }
+
     var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
     // Clear the interfaceElements
     {
         var node = document.getElementById('playback-holder');
-        if (node){feedbackHolder.removeChild(node);}
+        if (node) {
+            feedbackHolder.removeChild(node);
+        }
         node = document.getElementById('page-count');
-        if (node){document.getElementById('interface-buttons').removeChild(node);}
+        if (node) {
+            document.getElementById('interface-buttons').removeChild(node);
+        }
         node = document.getElementById('master-volume-holder-float');
-        if (node){feedbackHolder.removeChild(node);}
+        if (node) {
+            feedbackHolder.removeChild(node);
+        }
     }
-    
+
     // Populate the comparator object
-	interfaceContext.comparator = new comparator(audioHolderObject);
-    
-    for (var option of interfaceOptions)
-    {
-        if (option.type == "show")
-        {
-            switch(option.name) {
+    interfaceContext.comparator = new comparator(audioHolderObject);
+
+    for (var option of interfaceOptions) {
+        if (option.type == "show") {
+            switch (option.name) {
                 case "playhead":
                     var playbackHolder = document.getElementById('playback-holder');
-                    if (playbackHolder == null)
-                    {
+                    if (playbackHolder == null) {
                         playbackHolder = document.createElement('div');
                         playbackHolder.id = 'playback-holder';
                         playbackHolder.style.width = "100%";
@@ -190,201 +194,178 @@
                     break;
                 case "page-count":
                     var pagecountHolder = document.getElementById('page-count');
-                    if (pagecountHolder == null)
-                    {
+                    if (pagecountHolder == null) {
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                         document.getElementById('interface-buttons').appendChild(pagecountHolder);
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                     break;
                 case "volume":
-                    if (document.getElementById('master-volume-holder-float') == null)
-                    {
+                    if (document.getElementById('master-volume-holder-float') == null) {
                         feedbackHolder.appendChild(interfaceContext.volume.object);
                     }
                     break;
                 case "comments":
                     // Generate one comment box per presented page
-                    for (var element of audioEngineContext.audioObjects)
-                    {
+                    for (var element of audioEngineContext.audioObjects) {
                         interfaceContext.commentBoxes.createCommentBox(element);
                     }
-                    interfaceContext.commentBoxes.showCommentBoxes(commentHolder,true);
+                    interfaceContext.commentBoxes.showCommentBoxes(commentHolder, true);
                     break;
             }
         }
     }
-    
-    $(audioHolderObject.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		commentHolder.appendChild(node.holder);
-	});
-    
-	resizeWindow(null);
+
+    $(audioHolderObject.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        commentHolder.appendChild(node.holder);
+    });
+
+    resizeWindow(null);
 }
 
-function comparator(audioHolderObject)
-{	
-	this.comparatorBox = function(audioElement,id,text)
-	{
-		this.parent = audioElement;
-		this.id = id;
-		this.value = 0;
-		this.disabled = true;
-		this.box = document.createElement('div');
-		this.box.className = 'comparator-holder';
-		this.box.setAttribute('track-id',audioElement.id);
-		this.box.id = 'comparator-'+text;
-		this.selector = document.createElement('div');
-		this.selector.className = 'comparator-selector disabled';
-		var selectorText = document.createElement('span');
-		selectorText.textContent = text;
-		this.selector.appendChild(selectorText);
-		this.playback = document.createElement('button');
-		this.playback.className = 'comparator-button';
-		this.playback.disabled = true;
-		this.playback.textContent = "Listen";
-		this.box.appendChild(this.selector);
-		this.box.appendChild(this.playback);
-		this.selector.onclick = function(event)
-		{
-			var time = audioEngineContext.timer.getTestTime();
-			if ($(event.currentTarget).hasClass('disabled'))
-			{
-				console.log("Please wait until sample has loaded");
-				return;
-			}
-			if (audioEngineContext.status == 0)
-			{
-				interfaceContext.lightbox.post("Message","Please listen to the samples before making a selection");
-				console.log("Please listen to the samples before making a selection");
-				return;
+function comparator(audioHolderObject) {
+    this.comparatorBox = function (audioElement, id, text) {
+        this.parent = audioElement;
+        this.id = id;
+        this.value = 0;
+        this.disabled = true;
+        this.box = document.createElement('div');
+        this.box.className = 'comparator-holder';
+        this.box.setAttribute('track-id', audioElement.id);
+        this.box.id = 'comparator-' + text;
+        this.selector = document.createElement('div');
+        this.selector.className = 'comparator-selector disabled';
+        var selectorText = document.createElement('span');
+        selectorText.textContent = text;
+        this.selector.appendChild(selectorText);
+        this.playback = document.createElement('button');
+        this.playback.className = 'comparator-button';
+        this.playback.disabled = true;
+        this.playback.textContent = "Listen";
+        this.box.appendChild(this.selector);
+        this.box.appendChild(this.playback);
+        this.selector.onclick = function (event) {
+            var time = audioEngineContext.timer.getTestTime();
+            if ($(event.currentTarget).hasClass('disabled')) {
+                console.log("Please wait until sample has loaded");
+                return;
             }
-			var id = event.currentTarget.parentElement.getAttribute('track-id');
-			interfaceContext.comparator.selected = id;
+            if (audioEngineContext.status == 0) {
+                interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection");
+                console.log("Please listen to the samples before making a selection");
+                return;
+            }
+            var id = event.currentTarget.parentElement.getAttribute('track-id');
+            interfaceContext.comparator.selected = id;
             if ($(event.currentTarget).hasClass("selected")) {
                 $(".comparator-selector").removeClass('selected');
-                for (var i=0; i<interfaceContext.comparator.comparators.length; i++)
-                {
+                for (var i = 0; i < interfaceContext.comparator.comparators.length; i++) {
                     var obj = interfaceContext.comparator.comparators[i];
-                    obj.parent.metric.moved(time,0);
+                    obj.parent.metric.moved(time, 0);
                     obj.value = 0;
                 }
             } else {
                 $(".comparator-selector").removeClass('selected');
                 $(event.currentTarget).addClass('selected');
-                for (var i=0; i<interfaceContext.comparator.comparators.length; i++)
-                {
+                for (var i = 0; i < interfaceContext.comparator.comparators.length; i++) {
                     var obj = interfaceContext.comparator.comparators[i];
                     if (i == id) {
                         obj.value = 1;
                     } else {
                         obj.value = 0;
                     }
-                    obj.parent.metric.moved(time,obj.value);
+                    obj.parent.metric.moved(time, obj.value);
                 }
-                console.log("Selected "+id+' ('+time+')');
+                console.log("Selected " + id + ' (' + time + ')');
             }
-		};
-        this.playback.setAttribute("playstate","ready");
-		this.playback.onclick = function(event)
-		{
-			var id = event.currentTarget.parentElement.getAttribute('track-id');
-            if (event.currentTarget.getAttribute("playstate") == "ready")
-            {
+        };
+        this.playback.setAttribute("playstate", "ready");
+        this.playback.onclick = function (event) {
+            var id = event.currentTarget.parentElement.getAttribute('track-id');
+            if (event.currentTarget.getAttribute("playstate") == "ready") {
                 audioEngineContext.play(id);
             } else if (event.currentTarget.getAttribute("playstate") == "playing") {
                 audioEngineContext.stop();
             }
-			
-		};
-		
-		this.enable = function()
-		{
-			if (this.parent.state == 1)
-			{
-				$(this.selector).removeClass('disabled');
-				this.playback.disabled = false;
-			}
-		};
-		this.updateLoading = function(progress)
-		{
-			if (progress != 100)
-			{
-				progress = String(progress);
-				progress = progress.split('.')[0];
-				this.playback.textContent = progress+'%';
-			} else {
-				this.playback.textContent = "Play";
-			}
-		};
-        this.error = function() {
+
+        };
+
+        this.enable = function () {
+            if (this.parent.state == 1) {
+                $(this.selector).removeClass('disabled');
+                this.playback.disabled = false;
+            }
+        };
+        this.updateLoading = function (progress) {
+            if (progress != 100) {
+                progress = String(progress);
+                progress = progress.split('.')[0];
+                this.playback.textContent = progress + '%';
+            } else {
+                this.playback.textContent = "Play";
+            }
+        };
+        this.error = function () {
             // audioObject has an error!!
             this.playback.textContent = "Error";
             $(this.playback).addClass("error-colour");
         }
-        this.startPlayback = function()
-        {
+        this.startPlayback = function () {
             if (this.parent.specification.parent.playOne || specification.playOne) {
                 $('.comparator-button').text('Wait');
-                $('.comparator-button').attr("disabled","true");
+                $('.comparator-button').attr("disabled", "true");
                 $(this.playback).removeAttr("disabled");
             } else {
                 $('.comparator-button').text('Listen');
             }
             $(this.playback).text('Stop');
-            this.playback.setAttribute("playstate","playing");
+            this.playback.setAttribute("playstate", "playing");
         };
-        this.stopPlayback = function()
-        {
+        this.stopPlayback = function () {
             if (this.playback.getAttribute("playstate") == "playing") {
                 $('.comparator-button').text('Listen');
                 $('.comparator-button').removeAttr("disabled");
-                this.playback.setAttribute("playstate","ready");
+                this.playback.setAttribute("playstate", "ready");
             }
         };
-		this.exportXMLDOM = function(audioObject)
-		{
-			var node = storage.document.createElement('value');
-			node.textContent = this.value;
-			return node;
-		};
-		this.getValue = function() {
-			return this.value;	
-		};
-		this.getPresentedId = function()
-		{
-			return this.selector.children[0].textContent;
-		};
-		this.canMove = function()
-		{
-			return false;
-		};
-	};
-	
-	this.boxHolders = document.getElementById('box-holders');
-	this.boxHolders.innerHTML = "";
-	this.comparators = [];
-	this.selected = null;
-	
-	// First generate the Audio Objects for the Audio Engine
-	for (var index=0; index<audioHolderObject.audioElements.length; index++)
-	{
-		var element = audioHolderObject.audioElements[index];
+        this.exportXMLDOM = function (audioObject) {
+            var node = storage.document.createElement('value');
+            node.textContent = this.value;
+            return node;
+        };
+        this.getValue = function () {
+            return this.value;
+        };
+        this.getPresentedId = function () {
+            return this.selector.children[0].textContent;
+        };
+        this.canMove = function () {
+            return false;
+        };
+    };
+
+    this.boxHolders = document.getElementById('box-holders');
+    this.boxHolders.innerHTML = "";
+    this.comparators = [];
+    this.selected = null;
+
+    // First generate the Audio Objects for the Audio Engine
+    for (var index = 0; index < audioHolderObject.audioElements.length; index++) {
+        var element = audioHolderObject.audioElements[index];
         var audioObject = audioEngineContext.newTrack(element);
-		if (index == audioHolderObject.outsideReference || element.type == 'outside-reference')
-		{
-            var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder"));
-			audioObject.bindInterface(orNode);
+        if (index == audioHolderObject.outsideReference || element.type == 'outside-reference') {
+            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+            audioObject.bindInterface(orNode);
         } else {
             var label;
-            switch(audioObject.specification.parent.label) {
+            switch (audioObject.specification.parent.label) {
                 case "none":
                     label = "";
                     break;
                 case "number":
-                    label = ""+index;
+                    label = "" + index;
                     break;
                 case "letter":
                     label = String.fromCharCode(97 + index);
@@ -393,106 +374,109 @@
                     label = String.fromCharCode(65 + index);
                     break;
             }
-            var node = new this.comparatorBox(audioObject,index,label);
+            var node = new this.comparatorBox(audioObject, index, label);
             audioObject.bindInterface(node);
             this.comparators.push(node);
             this.boxHolders.appendChild(node.box);
         }
-	}
-	return this;
+    }
+    return this;
 }
 
-function resizeWindow(event)
-{
-	document.getElementById('submit').style.left = (window.innerWidth-250)/2 + 'px';
-	var numObj = interfaceContext.comparator.comparators.length;
-	var boxW = numObj*312;
+function resizeWindow(event) {
+    document.getElementById('submit').style.left = (window.innerWidth - 250) / 2 + 'px';
+    var numObj = interfaceContext.comparator.comparators.length;
+    var boxW = numObj * 312;
     var diff = window.innerWidth - boxW;
-    while (diff < 0)
-    {
-        numObj = Math.ceil(numObj/2);
-        boxW = numObj*312;
+    while (diff < 0) {
+        numObj = Math.ceil(numObj / 2);
+        boxW = numObj * 312;
         diff = window.innerWidth - boxW;
     }
-    document.getElementById('box-holders').style.marginLeft = diff/2 + 'px';
-    document.getElementById('box-holders').style.marginRight = diff/2 + 'px';
+    document.getElementById('box-holders').style.marginLeft = diff / 2 + 'px';
+    document.getElementById('box-holders').style.marginRight = diff / 2 + 'px';
     document.getElementById('box-holders').style.width = boxW + 'px';
-    
+
     var outsideRef = document.getElementById('outside-reference');
-	if(outsideRef != null)
-	{
-		outsideRef.style.left = (window.innerWidth-120)/2 + 'px';
-	}
+    if (outsideRef != null) {
+        outsideRef.style.left = (window.innerWidth - 120) / 2 + 'px';
+    }
 }
 
-function buttonSubmitClick()
-{
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkFragmentsFullyPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-            case 'scalerange':
-                // Check the scale has been used effectively
-                var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max);
-                if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
-				break;
-			}
+function buttonSubmitClick() {
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-	if (canContinue)
-	{
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Warning",'You have not started the test! Please click play on a sample to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-	}
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkFragmentsFullyPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale has been used effectively
+                    var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+    if (canContinue) {
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Warning", 'You have not started the test! Please click play on a sample to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+}
--- a/interfaces/ABX.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/ABX.css	Mon Nov 14 14:17:03 2016 +0000
@@ -1,80 +1,66 @@
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #fff
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #fff
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin-top: 20px;
+    width: auto;
+    height: 20px;
+    margin-top: 20px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 button.big-button {
-	width: 250px;
-	height: 40px;
-	font-size: 1.2em;
+    width: 250px;
+    height: 40px;
+    font-size: 1.2em;
 }
-
 div.comparator-holder {
-	width: 260px;
-	height: 300px;
-	border:  black 1px solid;
+    width: 260px;
+    height: 300px;
+    border: black 1px solid;
     float: left;
-	padding-top: 5px;
+    padding-top: 5px;
     margin: 25px;
 }
-
 div.comparator-selector {
-	width: 248px;
-	height: 250px;
-	border: black 1px solid;
-	position: relative;
-	background-color: #FF0000;
+    width: 248px;
+    height: 250px;
+    border: black 1px solid;
+    position: relative;
+    background-color: #FF0000;
     border-radius: 20px;
 }
-
 div.disabled {
-	background-color: #AAA;
+    background-color: #AAA;
 }
-
 div.selected {
-	background-color: #008000;
+    background-color: #008000;
 }
-
-div.comparator-selector.inactive{
-	background-color: yellow !important;
+div.comparator-selector.inactive {
+    background-color: yellow !important;
 }
-
 div.comparator-selector span {
-	font-size: 4em;
+    font-size: 4em;
 }
-
 button.comparator-button {
-	width: 250px;
-	height: 38px;
-	position: relative;
-	margin-top: 5px;
+    width: 250px;
+    height: 38px;
+    position: relative;
+    margin-top: 5px;
 }
-
 div.playhead {
     margin: 5px;
 }
-
 div#page-count {
     float: left;
     margin: 0px 5px;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
--- a/interfaces/ABX.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/ABX.js	Mon Nov 14 14:17:03 2016 +0000
@@ -7,12 +7,12 @@
 loadInterface();
 
 function loadInterface() {
-	// Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
-	// holding div's, or setting up any nodes which are present for the entire test sequence
-    
+    // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
+    // holding div's, or setting up any nodes which are present for the entire test sequence
+
     interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-    
-    Interface.prototype.checkScaleRange = function(min, max) {
+
+    Interface.prototype.checkScaleRange = function (min, max) {
         var page = testState.getCurrentTestPage();
         var audioObjects = audioEngineContext.audioObjects;
         var state = true;
@@ -21,151 +21,149 @@
         var maxRanking = -Infinity;
         for (var ao of audioObjects) {
             var rank = ao.interfaceDOM.getValue();
-            if (rank < minRanking) {minRanking = rank;}
-            if (rank > maxRanking) {maxRanking = rank;}
+            if (rank < minRanking) {
+                minRanking = rank;
+            }
+            if (rank > maxRanking) {
+                maxRanking = rank;
+            }
         }
-        if (maxRanking*100 < max) {
+        if (maxRanking * 100 < max) {
             str += "At least one fragment must be selected."
             state = false;
         }
         if (!state) {
             console.log(str);
             this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message",str);
+            interfaceContext.lightbox.post("Message", str);
         }
         return state;
     }
-    
+
     // Custom comparator Object
-	Interface.prototype.comparator = null;
-    
+    Interface.prototype.comparator = null;
+
     // The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	testContent.id = 'testContent';
-    
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+    testContent.id = 'testContent';
+
     // Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
     titleSpan.id = "test-title";
-    
+
     // Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-    
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
     var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle";
-	pagetitle.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	interfaceButtons.style.height = '25px';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	playback.style.float = 'left';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle";
+    pagetitle.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+    interfaceButtons.style.height = '25px';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    playback.style.float = 'left';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-	
-	// Construct the AB Boxes
-	var boxes = document.createElement('div');
-	boxes.align = "center";
-	boxes.id = "box-holders";
+        }
+    };
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
+    // Construct the AB Boxes
+    var boxes = document.createElement('div');
+    boxes.align = "center";
+    boxes.id = "box-holders";
     boxes.style.float = "left";
-	
-	var submit = document.createElement('button');
-	submit.id = "submit";
-	submit.onclick = buttonSubmitClick;
-	submit.className = "big-button";
-	submit.textContent = "submit";
-	submit.style.position = "relative";
-	submit.style.left = (window.innerWidth-250)/2 + 'px';
-		
-	feedbackHolder.appendChild(boxes);
-    
+
+    var submit = document.createElement('button');
+    submit.id = "submit";
+    submit.onclick = buttonSubmitClick;
+    submit.className = "big-button";
+    submit.textContent = "submit";
+    submit.style.position = "relative";
+    submit.style.left = (window.innerWidth - 250) / 2 + 'px';
+
+    feedbackHolder.appendChild(boxes);
+
     // Create holder for comment boxes
     var comments = document.createElement("div");
     comments.id = "comment-box-holder";
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(pagetitle);
-	testContent.appendChild(interfaceButtons);
-	testContent.appendChild(feedbackHolder);
-	testContent.appendChild(submit);
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(pagetitle);
+    testContent.appendChild(interfaceButtons);
+    testContent.appendChild(feedbackHolder);
+    testContent.appendChild(submit);
     testContent.appendChild(comments);
-	interfaceContext.insertPoint.appendChild(testContent);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
 };
 
-function loadTest(page)
-{
-	// Called each time a new test page is to be build. The page specification node is the only item passed in
+function loadTest(page) {
+    // Called each time a new test page is to be build. The page specification node is the only item passed in
     document.getElementById('box-holders').innerHTML = "";
-    
+
     var interfaceObj = page.interfaces;
-	if (interfaceObj.length > 1)
-	{
-		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
-	}
-	interfaceObj = interfaceObj[0];
-    
+    if (interfaceObj.length > 1) {
+        console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+    }
+    interfaceObj = interfaceObj[0];
+
     var commentHolder = document.getElementById("comment-box-holder");
     commentHolder.innerHTML = "";
-    
+
     // Set the page title
     if (typeof page.title == "string" && page.title.length > 0) {
         document.getElementById("test-title").textContent = page.title
     }
-	
-	if(interfaceObj.title != null)
-	{
-		document.getElementById("pageTitle").textContent = interfaceObj.title;
-	}
-    
+
+    if (interfaceObj.title != null) {
+        document.getElementById("pageTitle").textContent = interfaceObj.title;
+    }
+
     interfaceContext.comparator = new comparator(page);
-    
+
     var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
-    for (var option of interfaceOptions)
-    {
-        if (option.type == "show")
-        {
-            switch(option.name) {
+    for (var option of interfaceOptions) {
+        if (option.type == "show") {
+            switch (option.name) {
                 case "playhead":
                     var playbackHolder = document.getElementById('playback-holder');
-                    if (playbackHolder == null)
-                    {
+                    if (playbackHolder == null) {
                         playbackHolder = document.createElement('div');
                         playbackHolder.style.width = "100%";
                         playbackHolder.style.float = "left";
@@ -176,46 +174,41 @@
                     break;
                 case "page-count":
                     var pagecountHolder = document.getElementById('page-count');
-                    if (pagecountHolder == null)
-                    {
+                    if (pagecountHolder == null) {
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
                 case "volume":
-                    if (document.getElementById('master-volume-holder') == null)
-                    {
+                    if (document.getElementById('master-volume-holder') == null) {
                         feedbackHolder.appendChild(interfaceContext.volume.object);
                     }
                     break;
                 case "comments":
                     // Generate one comment box per presented page
-                    for (var element of audioEngineContext.audioObjects)
-                    {
+                    for (var element of audioEngineContext.audioObjects) {
                         interfaceContext.commentBoxes.createCommentBox(element);
                     }
-                    interfaceContext.commentBoxes.showCommentBoxes(commentHolder,true);
+                    interfaceContext.commentBoxes.showCommentBoxes(commentHolder, true);
                     break;
             }
         }
     }
-    
-    $(page.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		commentHolder.appendChild(node.holder);
-	});
-    
+
+    $(page.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        commentHolder.appendChild(node.holder);
+    });
+
     resizeWindow(null);
 }
 
-function comparator(page)
-{
+function comparator(page) {
     // Build prototype constructor
-    this.interfaceObject = function(element,label)
-    {
+    this.interfaceObject = function (element, label) {
         // An example node, you can make this however you want for each audioElement.
         // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
         // You attach them by calling audioObject.bindInterface( )
@@ -225,173 +218,158 @@
         this.disabled = true;
         this.box = document.createElement('div');
         this.box.className = 'comparator-holder';
-		this.box.setAttribute('track-id',element.id);
-		this.box.id = 'comparator-'+label;
+        this.box.setAttribute('track-id', element.id);
+        this.box.id = 'comparator-' + label;
         this.selector = document.createElement('div');
-		this.selector.className = 'comparator-selector disabled';
-		var selectorText = document.createElement('span');
-		selectorText.textContent = label;
-		this.selector.appendChild(selectorText);
-		this.playback = document.createElement('button');
-		this.playback.className = 'comparator-button';
-		this.playback.disabled = true;
-		this.playback.textContent = "Listen";
-		this.box.appendChild(this.selector);
-		this.box.appendChild(this.playback);
-        this.selector.onclick = function(event)
-		{
+        this.selector.className = 'comparator-selector disabled';
+        var selectorText = document.createElement('span');
+        selectorText.textContent = label;
+        this.selector.appendChild(selectorText);
+        this.playback = document.createElement('button');
+        this.playback.className = 'comparator-button';
+        this.playback.disabled = true;
+        this.playback.textContent = "Listen";
+        this.box.appendChild(this.selector);
+        this.box.appendChild(this.playback);
+        this.selector.onclick = function (event) {
             var label = event.currentTarget.children[0].textContent;
-            if (label == "X" || label == "x") {return;}
-			var time = audioEngineContext.timer.getTestTime();
-			if ($(event.currentTarget).hasClass('disabled'))
-			{
-				console.log("Please wait until sample has loaded");
-				return;
-			}
-			if (audioEngineContext.status == 0)
-			{
-				interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection");
-				console.log("Please listen to the samples before making a selection");
-				return;
+            if (label == "X" || label == "x") {
+                return;
             }
-			var id = event.currentTarget.parentElement.getAttribute('track-id');
-			interfaceContext.comparator.selected = id;
+            var time = audioEngineContext.timer.getTestTime();
+            if ($(event.currentTarget).hasClass('disabled')) {
+                console.log("Please wait until sample has loaded");
+                return;
+            }
+            if (audioEngineContext.status == 0) {
+                interfaceContext.lightbox.post("Message", "Please listen to the samples before making a selection");
+                console.log("Please listen to the samples before making a selection");
+                return;
+            }
+            var id = event.currentTarget.parentElement.getAttribute('track-id');
+            interfaceContext.comparator.selected = id;
             if ($(event.currentTarget).hasClass("selected")) {
                 $(".comparator-selector").removeClass('selected');
-                for (var i=0; i<interfaceContext.comparator.pair.length; i++)
-                {
+                for (var i = 0; i < interfaceContext.comparator.pair.length; i++) {
                     var obj = interfaceContext.comparator.pair[i];
-                    obj.parent.metric.moved(time,0);
+                    obj.parent.metric.moved(time, 0);
                     obj.value = 0;
                 }
             } else {
                 $(".comparator-selector").removeClass('selected');
                 $(event.currentTarget).addClass('selected');
-                for (var i=0; i<interfaceContext.comparator.pair.length; i++)
-                {
+                for (var i = 0; i < interfaceContext.comparator.pair.length; i++) {
                     var obj = interfaceContext.comparator.pair[i];
                     if (i == id) {
                         obj.value = 1;
                     } else {
                         obj.value = 0;
                     }
-                    obj.parent.metric.moved(time,obj.value);
+                    obj.parent.metric.moved(time, obj.value);
                 }
-                console.log("Selected "+id+' ('+time+')');
+                console.log("Selected " + id + ' (' + time + ')');
             }
-		};
-        this.playback.setAttribute("playstate","ready");
-		this.playback.onclick = function(event)
-		{
-			var id = event.currentTarget.parentElement.getAttribute('track-id');
-            if (event.currentTarget.getAttribute("playstate") == "ready")
-            {
+        };
+        this.playback.setAttribute("playstate", "ready");
+        this.playback.onclick = function (event) {
+            var id = event.currentTarget.parentElement.getAttribute('track-id');
+            if (event.currentTarget.getAttribute("playstate") == "ready") {
                 audioEngineContext.play(id);
             } else if (event.currentTarget.getAttribute("playstate") == "playing") {
                 audioEngineContext.stop();
             }
-			
-		};
-        this.enable = function()
-        {
+
+        };
+        this.enable = function () {
             // This is used to tell the interface object that playback of this node is ready
-            if (this.parent.state == 1)
-			{
-				$(this.selector).removeClass('disabled');
-				this.playback.disabled = false;
-			}
+            if (this.parent.state == 1) {
+                $(this.selector).removeClass('disabled');
+                this.playback.disabled = false;
+            }
         };
-        this.updateLoading = function(progress)
-        {
+        this.updateLoading = function (progress) {
             // progress is a value from 0 to 100 indicating the current download state of media files
-            if (progress != 100)
-			{
-				progress = String(progress);
-				progress = progress.split('.')[0];
-				this.playback.textContent = progress+'%';
-			} else {
-				this.playback.textContent = "Play";
-			}
+            if (progress != 100) {
+                progress = String(progress);
+                progress = progress.split('.')[0];
+                this.playback.textContent = progress + '%';
+            } else {
+                this.playback.textContent = "Play";
+            }
         };
-        this.error = function() {
+        this.error = function () {
             // audioObject has an error!!
             this.playback.textContent = "Error";
             $(this.playback).addClass("error-colour");
         };
-        this.startPlayback = function()
-        {
+        this.startPlayback = function () {
             if (this.parent.specification.parent.playOne || specification.playOne) {
                 $('.comparator-button').text('Wait');
-                $('.comparator-button').attr("disabled","true");
+                $('.comparator-button').attr("disabled", "true");
                 $(this.playback).removeAttr("disabled");
             } else {
                 $('.comparator-button').text('Listen');
             }
             $(this.playback).text('Stop');
-            this.playback.setAttribute("playstate","playing");
+            this.playback.setAttribute("playstate", "playing");
         };
-        this.stopPlayback = function()
-        {
+        this.stopPlayback = function () {
             if (this.playback.getAttribute("playstate") == "playing") {
                 $('.comparator-button').text('Listen');
                 $('.comparator-button').removeAttr("disabled");
-                this.playback.setAttribute("playstate","ready");
+                this.playback.setAttribute("playstate", "ready");
             }
         };
-        this.getValue = function()
-        {
+        this.getValue = function () {
             // Return the current value of the object. If there is no value, return 0
             return this.value;
         };
-        this.getPresentedId = function()
-        {
+        this.getPresentedId = function () {
             // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
             return this.selector.children[0].textContent;
         };
-        this.canMove = function()
-        {
+        this.canMove = function () {
             // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
             // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
             return false;
         };
-        this.exportXMLDOM = function(audioObject) {
+        this.exportXMLDOM = function (audioObject) {
             // Called by the audioObject holding this element to export the interface <value> node.
             // If there is no value node (such as outside reference), return null
             // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
             // Use storage.document.createElement('value'); to generate the XML node.
             var node = storage.document.createElement('value');
-			node.textContent = this.value;
-			return node;
+            node.textContent = this.value;
+            return node;
 
         };
-        this.error = function() {
+        this.error = function () {
             // If there is an error with the audioObject, this will be called to indicate a failure
         }
     };
     // Ensure there are only two comparisons per page
     if (page.audioElements.length != 2) {
-        console.error('FATAL - There must be 2 <audioelement> nodes on each <page>: '+page.id);
+        console.error('FATAL - There must be 2 <audioelement> nodes on each <page>: ' + page.id);
         return;
     }
     // Build the three audio elements
     this.pair = [];
     this.X = null;
     this.boxHolders = document.getElementById('box-holders');
-    for (var index=0; index<page.audioElements.length; index++) {
+    for (var index = 0; index < page.audioElements.length; index++) {
         var element = page.audioElements[index];
-        if (element.type != 'normal')
-		{
-			console.log("WARNING - ABX can only have normal elements. Page "+page.id+", Element "+element.id);
+        if (element.type != 'normal') {
+            console.log("WARNING - ABX can only have normal elements. Page " + page.id + ", Element " + element.id);
             element.type = "normal";
-		}
+        }
         var audioObject = audioEngineContext.newTrack(element);
         var label;
-        switch(audioObject.specification.parent.label) {
+        switch (audioObject.specification.parent.label) {
             case "none":
                 label = "";
                 break;
             case "number":
-                label = ""+index;
+                label = "" + index;
                 break;
             case "letter":
                 label = String.fromCharCode(97 + index);
@@ -400,7 +378,7 @@
                 label = String.fromCharCode(65 + index);
                 break;
         }
-        var node = new this.interfaceObject(audioObject,label);
+        var node = new this.interfaceObject(audioObject, label);
         audioObject.bindInterface(node);
         this.pair.push(node);
         this.boxHolders.appendChild(node.box);
@@ -408,25 +386,29 @@
     var elementId = Math.floor(Math.random() * 2); //Randomly pick A or B to be X
     var element = new page.audioElementNode(specification);
     for (var atr in page.audioElements[elementId]) {
-        eval("element."+atr+" = page.audioElements[elementId]."+atr);
+        eval("element." + atr + " = page.audioElements[elementId]." + atr);
     }
     element.id += "-X";
-    if (typeof element.name == "string") {element.name+="-X";}
+    if (typeof element.name == "string") {
+        element.name += "-X";
+    }
     page.audioElements.push(element);
     // Create the save place-holder for the 'X' element
     var root = testState.currentStore.XMLDOM;
     var aeNode = storage.document.createElement('audioelement');
-    aeNode.setAttribute('ref',element.id);
-    if (typeof element.name == "string"){aeNode.setAttribute('name',element.name);}
-    aeNode.setAttribute('type','normal');
-    aeNode.setAttribute('url',element.url);
-    aeNode.setAttribute('gain',element.gain);
+    aeNode.setAttribute('ref', element.id);
+    if (typeof element.name == "string") {
+        aeNode.setAttribute('name', element.name);
+    }
+    aeNode.setAttribute('type', 'normal');
+    aeNode.setAttribute('url', element.url);
+    aeNode.setAttribute('gain', element.gain);
     aeNode.appendChild(storage.document.createElement('metric'));
     root.appendChild(aeNode);
     // Build the 'X' element
     var audioObject = audioEngineContext.newTrack(element);
     var label;
-    switch(audioObject.specification.parent.label) {
+    switch (audioObject.specification.parent.label) {
         case "letter":
             label = "x";
             break;
@@ -434,98 +416,102 @@
             label = "X";
             break;
     }
-    var node = new this.interfaceObject(audioObject,label);
+    var node = new this.interfaceObject(audioObject, label);
     node.box.children[0].classList.add('inactive');
     audioObject.bindInterface(node);
     this.X = node;
     this.boxHolders.appendChild(node.box);
 }
 
-function resizeWindow(event)
-{
-	document.getElementById('submit').style.left = (window.innerWidth-250)/2 + 'px';
-	var numObj = 3;
-	var boxW = numObj*312;
+function resizeWindow(event) {
+    document.getElementById('submit').style.left = (window.innerWidth - 250) / 2 + 'px';
+    var numObj = 3;
+    var boxW = numObj * 312;
     var diff = window.innerWidth - boxW;
-    while (diff < 0)
-    {
-        numObj = Math.ceil(numObj/2);
-        boxW = numObj*312;
+    while (diff < 0) {
+        numObj = Math.ceil(numObj / 2);
+        boxW = numObj * 312;
         diff = window.innerWidth - boxW;
     }
-    document.getElementById('box-holders').style.marginLeft = diff/2 + 'px';
-    document.getElementById('box-holders').style.marginRight = diff/2 + 'px';
+    document.getElementById('box-holders').style.marginLeft = diff / 2 + 'px';
+    document.getElementById('box-holders').style.marginRight = diff / 2 + 'px';
     document.getElementById('box-holders').style.width = boxW + 'px';
 }
 
-function buttonSubmitClick()
-{
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkFragmentsFullyPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-            case 'scalerange':
-                // Check the scale has been used effectively
-                var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max);
-                if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
-				break;
-			}
+function buttonSubmitClick() {
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-	if (canContinue)
-	{
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Warning",'You have not started the test! Please listen to a sample to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-	}
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkFragmentsFullyPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale has been used effectively
+                    var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+    if (canContinue) {
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Warning", 'You have not started the test! Please listen to a sample to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+}
--- a/interfaces/ape.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/ape.css	Mon Nov 14 14:17:03 2016 +0000
@@ -2,103 +2,90 @@
  * Hold any style information for APE interface. Customise if you like to make the interface your own!
  * 
  */
+
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #ddd
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #ddd
 }
-
 div.title {
-	/* Specify any colouring for the title */
+    /* Specify any colouring for the title */
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin-top: 5px;
-	margin-bottom: 10px;
+    width: auto;
+    height: 20px;
+    margin-top: 5px;
+    margin-bottom: 10px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 div.slider {
-	/* Specify any structure for the slider holder interface */
-	background-color: #eee;
-	height: 150px;
-	margin: 5px 50px;
-	-moz-user-select: -moz-none;
-	-khtml-user-select: none;
-	-webkit-user-select: none;
+    /* Specify any structure for the slider holder interface */
+    background-color: #eee;
+    height: 150px;
+    margin: 5px 50px;
+    -moz-user-select: -moz-none;
+    -khtml-user-select: none;
+    -webkit-user-select: none;
 }
-
 div.sliderScale {
-	width: 100%;
-	min-height: 30px;
-	-moz-user-select: -moz-none;
-	-khtml-user-select: none;
-	-webkit-user-select: none;
+    width: 100%;
+    min-height: 30px;
+    -moz-user-select: -moz-none;
+    -khtml-user-select: none;
+    -webkit-user-select: none;
 }
-
 div.sliderScale span {
-	/* Any formatting of text below scale */
-	font-size: 1.2em;
-	min-width: 5px;
+    /* Any formatting of text below scale */
+    font-size: 1.2em;
+    min-width: 5px;
     max-width: 100px;
     text-align: center;
-	height: 20px;
-	position: absolute;
+    height: 20px;
+    position: absolute;
 }
-
 div.track-slider {
-	/* Specify any structure for the slider objects */
-	position: absolute;
-	height: inherit;
-	width: 12px;
-	float: left;
-	background-color: rgb(100,200,100);
-	-moz-user-select: -moz-none;
-	-khtml-user-select: none;
-	-webkit-user-select: none;
+    /* Specify any structure for the slider objects */
+    position: absolute;
+    height: inherit;
+    width: 12px;
+    float: left;
+    background-color: rgb(100, 200, 100);
+    -moz-user-select: -moz-none;
+    -khtml-user-select: none;
+    -webkit-user-select: none;
     border: 1px solid black;
 }
-
 div#outside-reference-holder {
     display: flex;
     align-content: center;
     justify-content: center;
     margin-bottom: 5px;
 }
-
 div.outside-reference {
-	width:120px;
+    width: 120px;
     text-align: center;
-	height:20px;
-	background-color: rgb(100,200,100);
+    height: 20px;
+    background-color: rgb(100, 200, 100);
     position: inherit;
     margin: 0px 5px;
 }
-
 div.track-slider-disabled {
-	background-color: rgb(100,100,100);
+    background-color: rgb(100, 100, 100);
 }
-
 div.track-slider-playing {
-	background-color: #FF0000;
+    background-color: #FF0000;
 }
-
 div.comment-box-playing {
-	background-color: #FFDDDD;
+    background-color: #FFDDDD;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
     left: 120px;
-}
\ No newline at end of file
+}
--- a/interfaces/ape.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/ape.js	Mon Nov 14 14:17:03 2016 +0000
@@ -8,472 +8,440 @@
 loadInterface();
 
 function loadInterface() {
-	
-	// Get the dimensions of the screen available to the page
-	var width = window.innerWidth;
-	var height = window.innerHeight;
-	
-	// The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	
-	testContent.id = 'testContent';
-	
-	// Bindings for interfaceContext
-	interfaceContext.checkAllPlayed = function()
-	{
-		hasBeenPlayed = audioEngineContext.checkAllPlayed();
-		if (hasBeenPlayed.length > 0) // if a fragment has not been played yet
-	    {
-	    	var str = "";
-	    	if (hasBeenPlayed.length > 1) {
-		    	for (var i=0; i<hasBeenPlayed.length; i++) {
+
+    // Get the dimensions of the screen available to the page
+    var width = window.innerWidth;
+    var height = window.innerHeight;
+
+    // The injection point into the HTML page
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+
+    testContent.id = 'testContent';
+
+    // Bindings for interfaceContext
+    interfaceContext.checkAllPlayed = function () {
+        hasBeenPlayed = audioEngineContext.checkAllPlayed();
+        if (hasBeenPlayed.length > 0) // if a fragment has not been played yet
+        {
+            var str = "";
+            if (hasBeenPlayed.length > 1) {
+                for (var i = 0; i < hasBeenPlayed.length; i++) {
                     var ao_id = audioEngineContext.audioObjects[hasBeenPlayed[i]].interfaceDOM.getPresentedId();
-		    		str = str + ao_id; // start from 1
-		    		if (i < hasBeenPlayed.length-2){
-		    			str += ", ";
-		    		} else if (i == hasBeenPlayed.length-2) {
-		    			str += " or ";
-		    		}
-		    	}
+                    str = str + ao_id; // start from 1
+                    if (i < hasBeenPlayed.length - 2) {
+                        str += ", ";
+                    } else if (i == hasBeenPlayed.length - 2) {
+                        str += " or ";
+                    }
+                }
                 str = 'You have not played fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.';
-	       } else {
-               str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
-           }
+            } else {
+                str = 'You have not played fragment ' + (audioEngineContext.audioObjects[hasBeenPlayed[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
+            }
             this.storeErrorNode(str);
-            interfaceContext.lightbox.post("Message",str);
-	        return false;
-	    }
-	    return true;
-	};
-	
-	interfaceContext.checkAllMoved = function() {
-		var state = true;
-		var str = 'You have not moved the following sliders. ';
-		for (var i=0; i<this.interfaceSliders.length; i++)
-		{
-			var interfaceTID = [];
-			for (var j=0; j<this.interfaceSliders[i].metrics.length; j++)
-			{
+            interfaceContext.lightbox.post("Message", str);
+            return false;
+        }
+        return true;
+    };
+
+    interfaceContext.checkAllMoved = function () {
+        var state = true;
+        var str = 'You have not moved the following sliders. ';
+        for (var i = 0; i < this.interfaceSliders.length; i++) {
+            var interfaceTID = [];
+            for (var j = 0; j < this.interfaceSliders[i].metrics.length; j++) {
                 var ao_id = this.interfaceSliders[i].sliders[j].getAttribute("trackIndex");
-				if (this.interfaceSliders[i].metrics[j].wasMoved == false && audioEngineContext.audioObjects[ao_id].interfaceDOM.canMove())
-				{
-					state = false;
-					interfaceTID.push(j);
-				}
-			}
-			if (interfaceTID.length != 0)
-			{
-				var interfaceName = this.interfaceSliders[i].interfaceObject.title;
-				if (interfaceName == undefined) {
-					str += 'On axis '+String(i+1)+' you must move ';
-				} else {
-					str += 'On axis "'+interfaceName+'" you must move ';
-				}
-				if (interfaceTID.length == 1)
-				{
-					str += 'slider '+(audioEngineContext.audioObjects[interfaceTID[0]].interfaceDOM.getPresentedId())+'. '; // start from 1
-				}
-				else {
-					str += 'sliders ';
-					for (var k=0; k<interfaceTID.length-1; k++)
-					{
-						str += (audioEngineContext.audioObjects[interfaceTID[k]].interfaceDOM.getPresentedId())+', '; // start from 1
-					}
-					str += (audioEngineContext.audioObjects[interfaceTID[interfaceTID.length-1]].interfaceDOM.getPresentedId()) +'. ';
-				}
-			}
-		}
-		if (state != true)
-		{
+                if (this.interfaceSliders[i].metrics[j].wasMoved == false && audioEngineContext.audioObjects[ao_id].interfaceDOM.canMove()) {
+                    state = false;
+                    interfaceTID.push(j);
+                }
+            }
+            if (interfaceTID.length != 0) {
+                var interfaceName = this.interfaceSliders[i].interfaceObject.title;
+                if (interfaceName == undefined) {
+                    str += 'On axis ' + String(i + 1) + ' you must move ';
+                } else {
+                    str += 'On axis "' + interfaceName + '" you must move ';
+                }
+                if (interfaceTID.length == 1) {
+                    str += 'slider ' + (audioEngineContext.audioObjects[interfaceTID[0]].interfaceDOM.getPresentedId()) + '. '; // start from 1
+                } else {
+                    str += 'sliders ';
+                    for (var k = 0; k < interfaceTID.length - 1; k++) {
+                        str += (audioEngineContext.audioObjects[interfaceTID[k]].interfaceDOM.getPresentedId()) + ', '; // start from 1
+                    }
+                    str += (audioEngineContext.audioObjects[interfaceTID[interfaceTID.length - 1]].interfaceDOM.getPresentedId()) + '. ';
+                }
+            }
+        }
+        if (state != true) {
             this.storeErrorNode(str);
-			interfaceContext.lightbox.post("Message",str);
-			console.log(str);
-		}
-		return state;
-	};
-	
-	Interface.prototype.checkAllCommented = function() {
-		var audioObjs = audioEngineContext.audioObjects;
-		var audioHolder = testState.stateMap[testState.stateIndex];
-		var state = true;
-		if (audioHolder.elementComments) {
-			var strNums = [];
-			for (var i=0; i<audioObjs.length; i++)
-			{
-				if (audioObjs[i].commentDOM.trackCommentBox.value.length == 0) {
-					state = false;
-					strNums.push(i);
-				}
-			}
-			if (state == false) {
+            interfaceContext.lightbox.post("Message", str);
+            console.log(str);
+        }
+        return state;
+    };
+
+    Interface.prototype.checkAllCommented = function () {
+        var audioObjs = audioEngineContext.audioObjects;
+        var audioHolder = testState.stateMap[testState.stateIndex];
+        var state = true;
+        if (audioHolder.elementComments) {
+            var strNums = [];
+            for (var i = 0; i < audioObjs.length; i++) {
+                if (audioObjs[i].commentDOM.trackCommentBox.value.length == 0) {
+                    state = false;
+                    strNums.push(i);
+                }
+            }
+            if (state == false) {
                 var str = "";
-				if (strNums.length > 1) {
-					
-			    	for (var i=0; i<strNums.length; i++) {
+                if (strNums.length > 1) {
+
+                    for (var i = 0; i < strNums.length; i++) {
                         var ao_id = audioEngineContext.audioObjects[strNums[i]].interfaceDOM.getPresentedId();
-			    		str = str + (ao_id); // start from 1
-			    		if (i < strNums.length-2){
-			    			str += ", ";
-			    		} else if (i == strNums.length-2) {
-			    			str += " or ";
-			    		}
-			    	}
+                        str = str + (ao_id); // start from 1
+                        if (i < strNums.length - 2) {
+                            str += ", ";
+                        } else if (i == strNums.length - 2) {
+                            str += " or ";
+                        }
+                    }
                     str = 'You have not commented on fragments ' + str + ' yet. Please listen, rate and comment all samples before submitting.';
-		       } else {
-                   str = 'You have not commented on fragment ' + (audioEngineContext.audioObjects[strNums[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
-		       }
+                } else {
+                    str = 'You have not commented on fragment ' + (audioEngineContext.audioObjects[strNums[0]].interfaceDOM.getPresentedId()) + ' yet. Please listen, rate and comment all samples before submitting.';
+                }
                 this.storeErrorNode(str);
-                interfaceContext.lightbox.post("Message",str);
+                interfaceContext.lightbox.post("Message", str);
                 console.log(str);
-			}
-		}
-		return state;
-	};
-	
-	Interface.prototype.checkScaleRange = function()
-	{
-		var audioObjs = audioEngineContext.audioObjects;
-		var audioHolder = testState.stateMap[testState.stateIndex];
-		var state = true;
-		var str = '';
-		for (var i=0; i<this.interfaceSliders.length; i++)
-		{
-			var minScale;
-			var maxScale;
-			var interfaceObject = interfaceContext.interfaceSliders[0].interfaceObject;
-			for (var j=0; j<interfaceObject.options.length; j++)
-			{
-				if (interfaceObject.options[j].check == "scalerange") {
-					minScale = interfaceObject.options[j].min;
-					maxScale = interfaceObject.options[j].max;
-					break;
-				}
-			}
-			var minRanking = convSliderPosToRate(this.interfaceSliders[i].sliders[0]);
-			var maxRanking = minRanking;
-			for (var j=1; j<this.interfaceSliders[i].sliders.length; j++)
-			{
-				var ranking = convSliderPosToRate(this.interfaceSliders[i].sliders[j]);
-				if (ranking < minRanking)
-				{
-					minRanking = ranking;
-				} else if (ranking > maxRanking)
-				{
-					maxRanking = ranking;
-				}
-			}
-			if (minRanking > minScale || maxRanking < maxScale)
-			{
-				state = false;
-				str += 'On axis "'+this.interfaceSliders[i].interfaceObject.title+'" you have not used the full width of the scale. ';
-			}
-		}
-		if (state != true)
-		{
+            }
+        }
+        return state;
+    };
+
+    Interface.prototype.checkScaleRange = function () {
+        var audioObjs = audioEngineContext.audioObjects;
+        var audioHolder = testState.stateMap[testState.stateIndex];
+        var state = true;
+        var str = '';
+        for (var i = 0; i < this.interfaceSliders.length; i++) {
+            var minScale;
+            var maxScale;
+            var interfaceObject = interfaceContext.interfaceSliders[0].interfaceObject;
+            for (var j = 0; j < interfaceObject.options.length; j++) {
+                if (interfaceObject.options[j].check == "scalerange") {
+                    minScale = interfaceObject.options[j].min;
+                    maxScale = interfaceObject.options[j].max;
+                    break;
+                }
+            }
+            var minRanking = convSliderPosToRate(this.interfaceSliders[i].sliders[0]);
+            var maxRanking = minRanking;
+            for (var j = 1; j < this.interfaceSliders[i].sliders.length; j++) {
+                var ranking = convSliderPosToRate(this.interfaceSliders[i].sliders[j]);
+                if (ranking < minRanking) {
+                    minRanking = ranking;
+                } else if (ranking > maxRanking) {
+                    maxRanking = ranking;
+                }
+            }
+            if (minRanking > minScale || maxRanking < maxScale) {
+                state = false;
+                str += 'On axis "' + this.interfaceSliders[i].interfaceObject.title + '" you have not used the full width of the scale. ';
+            }
+        }
+        if (state != true) {
             this.storeErrorNode(str);
-			interfaceContext.lightbox.post("Message",str);
-			console.log(str);
-		}
-		return state;
-	};
-	
-	Interface.prototype.objectSelected = null;
-	Interface.prototype.objectMoved = false;
-	Interface.prototype.selectObject = function(object)
-	{
-		if (this.objectSelected == null)
-		{
-			this.objectSelected = object;
-			this.objectMoved = false;
-		}
-	};
-	Interface.prototype.moveObject = function()
-	{
-		if (this.objectMoved == false)
-		{
-			this.objectMoved = true;
-		}
-	};
-	Interface.prototype.releaseObject = function()
-	{
-		this.objectSelected = null;
-		this.objectMoved = false;
-	};
-	Interface.prototype.getSelectedObject = function()
-	{
-		return this.objectSelected;
-	};
-	Interface.prototype.hasSelectedObjectMoved = function()
-	{
-		return this.objectMoved;
-	};
-	
-	// Bindings for slider interfaces
-	Interface.prototype.interfaceSliders = [];
-	
-	// Bindings for audioObjects
-	
-	// Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
+            interfaceContext.lightbox.post("Message", str);
+            console.log(str);
+        }
+        return state;
+    };
+
+    Interface.prototype.objectSelected = null;
+    Interface.prototype.objectMoved = false;
+    Interface.prototype.selectObject = function (object) {
+        if (this.objectSelected == null) {
+            this.objectSelected = object;
+            this.objectMoved = false;
+        }
+    };
+    Interface.prototype.moveObject = function () {
+        if (this.objectMoved == false) {
+            this.objectMoved = true;
+        }
+    };
+    Interface.prototype.releaseObject = function () {
+        this.objectSelected = null;
+        this.objectMoved = false;
+    };
+    Interface.prototype.getSelectedObject = function () {
+        return this.objectSelected;
+    };
+    Interface.prototype.hasSelectedObjectMoved = function () {
+        return this.objectMoved;
+    };
+
+    // Bindings for slider interfaces
+    Interface.prototype.interfaceSliders = [];
+
+    // Bindings for audioObjects
+
+    // Create the top div for the Title element
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
     titleSpan.id = "test-title";
-	
-	// Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+
+    // Set title to that defined in XML, else set to default
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-	// Create Submit (save) button
-	var submit = document.createElement("button");
-	submit.innerHTML = 'Next';
-	submit.onclick = buttonSubmitClick;
-	submit.id = 'submit-button';
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	interfaceButtons.appendChild(submit);
-	
-	var sliderHolder = document.createElement("div");
-	sliderHolder.id = "slider-holder";
-	
+        }
+    };
+    // Create Submit (save) button
+    var submit = document.createElement("button");
+    submit.innerHTML = 'Next';
+    submit.onclick = buttonSubmitClick;
+    submit.id = 'submit-button';
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+    interfaceButtons.appendChild(submit);
+
+    var sliderHolder = document.createElement("div");
+    sliderHolder.id = "slider-holder";
+
     // Create outside reference holder
     var outsideRef = document.createElement("div");
     outsideRef.id = "outside-reference-holder";
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-	
-	testContent.style.zIndex = 1;
-	interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(interfaceButtons);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
+    testContent.style.zIndex = 1;
+    interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
-	testContent.appendChild(sliderHolder);
-	testContent.appendChild(feedbackHolder);
-	interfaceContext.insertPoint.appendChild(testContent);
+    testContent.appendChild(sliderHolder);
+    testContent.appendChild(feedbackHolder);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
-	
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
+
 }
 
-function loadTest(audioHolderObject)
-{
-	var width = window.innerWidth;
-	var height = window.innerHeight;
-	var id = audioHolderObject.id;
-	
-	interfaceContext.interfaceSliders = [];
-	
-	var feedbackHolder = document.getElementById('feedbackHolder');
-	var sliderHolder = document.getElementById('slider-holder');
-	feedbackHolder.innerHTML = "";
-	sliderHolder.innerHTML = "";
-    
+function loadTest(audioHolderObject) {
+    var width = window.innerWidth;
+    var height = window.innerHeight;
+    var id = audioHolderObject.id;
+
+    interfaceContext.interfaceSliders = [];
+
+    var feedbackHolder = document.getElementById('feedbackHolder');
+    var sliderHolder = document.getElementById('slider-holder');
+    feedbackHolder.innerHTML = "";
+    sliderHolder.innerHTML = "";
+
     // Set the page title
     if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) {
         document.getElementById("test-title").textContent = audioHolderObject.title
     }
-	
-	
-	// Delete outside reference
-	document.getElementById("outside-reference-holder").innerHTML = "";
-	
-	var interfaceObj = audioHolderObject.interfaces;
-	for (var k=0; k<interfaceObj.length; k++) {
-		// Create the div box to center align
-		interfaceContext.interfaceSliders.push(new interfaceSliderHolder(interfaceObj[k]));
-	}
-    
+
+
+    // Delete outside reference
+    document.getElementById("outside-reference-holder").innerHTML = "";
+
+    var interfaceObj = audioHolderObject.interfaces;
+    for (var k = 0; k < interfaceObj.length; k++) {
+        // Create the div box to center align
+        interfaceContext.interfaceSliders.push(new interfaceSliderHolder(interfaceObj[k]));
+    }
+
     var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces);
-    for (var k=0; k<interfaceList.length; k++)
-    {
-        for (var i=0; i<interfaceList[k].options.length; i++)
-        {
-            if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead')
-            {
+    for (var k = 0; k < interfaceList.length; k++) {
+        for (var i = 0; i < interfaceList[k].options.length; i++) {
+            if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead') {
                 var playbackHolder = document.getElementById('playback-holder');
-                if (playbackHolder == null)
-                {
+                if (playbackHolder == null) {
                     playbackHolder = document.createElement('div');
                     playbackHolder.style.width = "100%";
                     playbackHolder.align = 'center';
                     playbackHolder.appendChild(interfaceContext.playhead.object);
                     feedbackHolder.appendChild(playbackHolder);
                 }
-            } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count')
-            {
+            } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') {
                 var pagecountHolder = document.getElementById('page-count');
-                if (pagecountHolder == null)
-                {
+                if (pagecountHolder == null) {
                     pagecountHolder = document.createElement('div');
                     pagecountHolder.id = 'page-count';
                 }
-                pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                 var inject = document.getElementById('interface-buttons');
                 inject.appendChild(pagecountHolder);
             } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') {
-                if (document.getElementById('master-volume-holder') == null)
-                {
+                if (document.getElementById('master-volume-holder') == null) {
                     feedbackHolder.appendChild(interfaceContext.volume.object);
                 }
             } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') {
                 var commentHolder = document.createElement('div');
                 commentHolder.id = 'commentHolder';
                 document.getElementById('testContent').appendChild(commentHolder);
-                interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+                interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                 break;
             }
         }
     }
-	
-	var commentBoxPrefix = "Comment on fragment";
-	
-	var commentShow = audioHolderObject.elementComments;
-	
-	var loopPlayback = audioHolderObject.loop;
 
-	currentTestHolder = document.createElement('audioHolder');
-	currentTestHolder.id = audioHolderObject.id;
-	currentTestHolder.repeatCount = audioHolderObject.repeatCount;
-    
-	// Find all the audioElements from the audioHolder
-	$(audioHolderObject.audioElements).each(function(index,element){
-		// Find URL of track
-		// In this jQuery loop, variable 'this' holds the current audioElement.
-		var audioObject = audioEngineContext.newTrack(element);
-		// Check if an outside reference
-		if (element.type == 'outside-reference')
-		{
-			// Construct outside reference;
-			var orNode = new outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder"));
-			audioObject.bindInterface(orNode);
-		} else {
-			// Create a slider per track
-			var sliderNode = new sliderObject(audioObject,interfaceObj,index);
-			audioObject.bindInterface(sliderNode);
+    var commentBoxPrefix = "Comment on fragment";
+
+    var commentShow = audioHolderObject.elementComments;
+
+    var loopPlayback = audioHolderObject.loop;
+
+    currentTestHolder = document.createElement('audioHolder');
+    currentTestHolder.id = audioHolderObject.id;
+    currentTestHolder.repeatCount = audioHolderObject.repeatCount;
+
+    // Find all the audioElements from the audioHolder
+    $(audioHolderObject.audioElements).each(function (index, element) {
+        // Find URL of track
+        // In this jQuery loop, variable 'this' holds the current audioElement.
+        var audioObject = audioEngineContext.newTrack(element);
+        // Check if an outside reference
+        if (element.type == 'outside-reference') {
+            // Construct outside reference;
+            var orNode = new outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+            audioObject.bindInterface(orNode);
+        } else {
+            // Create a slider per track
+            var sliderNode = new sliderObject(audioObject, interfaceObj, index);
+            audioObject.bindInterface(sliderNode);
             interfaceContext.commentBoxes.createCommentBox(audioObject);
-		}
-	});
-	
-	// Initialse the interfaceSlider object metrics
-	
-	$('.track-slider').mousedown(function(event) {
-		interfaceContext.selectObject($(this)[0]);
-	});
-	$('.track-slider').on('touchstart',null,function(event) {
-		interfaceContext.selectObject($(this)[0]);
-	});
-	
-	$('.track-slider').mousemove(function(event) {
-		event.preventDefault();
-	});
-	
-	$('.slider').mousemove(function(event) {
-		event.preventDefault();
-		var obj = interfaceContext.getSelectedObject();
-		if (obj == null) {return;}
-        var move = event.clientX-6;
+        }
+    });
+
+    // Initialse the interfaceSlider object metrics
+
+    $('.track-slider').mousedown(function (event) {
+        interfaceContext.selectObject($(this)[0]);
+    });
+    $('.track-slider').on('touchstart', null, function (event) {
+        interfaceContext.selectObject($(this)[0]);
+    });
+
+    $('.track-slider').mousemove(function (event) {
+        event.preventDefault();
+    });
+
+    $('.slider').mousemove(function (event) {
+        event.preventDefault();
+        var obj = interfaceContext.getSelectedObject();
+        if (obj == null) {
+            return;
+        }
+        var move = event.clientX - 6;
         var w = $(event.currentTarget).width();
-        move = Math.max(50,move);
-        move = Math.min(w+50,move);
-		$(obj).css("left",move + "px");
-		interfaceContext.moveObject();
-	});
-	
-	$('.slider').on('touchmove',null,function(event) {
-		event.preventDefault();
-		var obj = interfaceContext.getSelectedObject();
-		if (obj == null) {return;}
-		var move = event.originalEvent.targetTouches[0].clientX - 6;
+        move = Math.max(50, move);
+        move = Math.min(w + 50, move);
+        $(obj).css("left", move + "px");
+        interfaceContext.moveObject();
+    });
+
+    $('.slider').on('touchmove', null, function (event) {
+        event.preventDefault();
+        var obj = interfaceContext.getSelectedObject();
+        if (obj == null) {
+            return;
+        }
+        var move = event.originalEvent.targetTouches[0].clientX - 6;
         var w = $(event.currentTarget).width();
-        move = Math.max(50,move);
-        move = Math.min(w+50,move);
-		$(obj).css("left",move + "px");
-		interfaceContext.moveObject();
-	});
+        move = Math.max(50, move);
+        move = Math.min(w + 50, move);
+        $(obj).css("left", move + "px");
+        interfaceContext.moveObject();
+    });
 
-	$(document).mouseup(function(event){
-		event.preventDefault();
-		var obj = interfaceContext.getSelectedObject();
-		if (obj == null) {return;}
-		var interfaceID = obj.parentElement.getAttribute("interfaceid");
-		var trackID = obj.getAttribute("trackindex");
-		if (interfaceContext.hasSelectedObjectMoved() == true)
-		{
-			var l = $(obj).css("left");
-			var id = obj.getAttribute('trackIndex');
-			var time = audioEngineContext.timer.getTestTime();
-			var rate = convSliderPosToRate(obj);
-			audioEngineContext.audioObjects[id].metric.moved(time,rate);
-			interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time,rate);
-			console.log("slider "+id+" moved to "+rate+' ('+time+')');
-            obj.setAttribute("slider-value",convSliderPosToRate(obj));
-		} else {
-			var id = Number(obj.attributes['trackIndex'].value);
-			//audioEngineContext.metric.sliderPlayed(id);
-			audioEngineContext.play(id);
-		}
-		interfaceContext.releaseObject();
-	});
-	
-	$('.slider').on('touchend',null,function(event){
-		var obj = interfaceContext.getSelectedObject();
-		if (obj == null) {return;}
-		var interfaceID = obj.parentElement.getAttribute("interfaceid");
-		var trackID = obj.getAttribute("trackindex");
-		if (interfaceContext.hasSelectedObjectMoved() == true)
-		{
-			var l = $(obj).css("left");
-			var id = obj.getAttribute('trackIndex');
-			var time = audioEngineContext.timer.getTestTime();
-			var rate = convSliderPosToRate(obj);
-			audioEngineContext.audioObjects[id].metric.moved(time,rate);
-			interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time,rate);
-			console.log("slider "+id+" moved to "+rate+' ('+time+')');
-		}
-		interfaceContext.releaseObject();
-	});
-	
+    $(document).mouseup(function (event) {
+        event.preventDefault();
+        var obj = interfaceContext.getSelectedObject();
+        if (obj == null) {
+            return;
+        }
+        var interfaceID = obj.parentElement.getAttribute("interfaceid");
+        var trackID = obj.getAttribute("trackindex");
+        if (interfaceContext.hasSelectedObjectMoved() == true) {
+            var l = $(obj).css("left");
+            var id = obj.getAttribute('trackIndex');
+            var time = audioEngineContext.timer.getTestTime();
+            var rate = convSliderPosToRate(obj);
+            audioEngineContext.audioObjects[id].metric.moved(time, rate);
+            interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
+            console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
+            obj.setAttribute("slider-value", convSliderPosToRate(obj));
+        } else {
+            var id = Number(obj.attributes['trackIndex'].value);
+            //audioEngineContext.metric.sliderPlayed(id);
+            audioEngineContext.play(id);
+        }
+        interfaceContext.releaseObject();
+    });
+
+    $('.slider').on('touchend', null, function (event) {
+        var obj = interfaceContext.getSelectedObject();
+        if (obj == null) {
+            return;
+        }
+        var interfaceID = obj.parentElement.getAttribute("interfaceid");
+        var trackID = obj.getAttribute("trackindex");
+        if (interfaceContext.hasSelectedObjectMoved() == true) {
+            var l = $(obj).css("left");
+            var id = obj.getAttribute('trackIndex');
+            var time = audioEngineContext.timer.getTestTime();
+            var rate = convSliderPosToRate(obj);
+            audioEngineContext.audioObjects[id].metric.moved(time, rate);
+            interfaceContext.interfaceSliders[interfaceID].metrics[trackID].moved(time, rate);
+            console.log("slider " + id + " moved to " + rate + ' (' + time + ')');
+        }
+        interfaceContext.releaseObject();
+    });
+
     var interfaceList = audioHolderObject.interfaces.concat(specification.interfaces);
-    for (var k=0; k<interfaceList.length; k++)
-    {
-        for (var i=0; i<interfaceList[k].options.length; i++)
-        {
-            if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead')
-            {
+    for (var k = 0; k < interfaceList.length; k++) {
+        for (var i = 0; i < interfaceList[k].options.length; i++) {
+            if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'playhead') {
                 var playbackHolder = document.getElementById('playback-holder');
-                if (playbackHolder == null)
-                {
+                if (playbackHolder == null) {
                     playbackHolder = document.createElement('div');
                     playbackHolder.id = "playback-holder";
                     playbackHolder.style.width = "100%";
@@ -481,162 +449,152 @@
                     playbackHolder.appendChild(interfaceContext.playhead.object);
                     feedbackHolder.appendChild(playbackHolder);
                 }
-            } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count')
-            {
+            } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'page-count') {
                 var pagecountHolder = document.getElementById('page-count');
-                if (pagecountHolder == null)
-                {
+                if (pagecountHolder == null) {
                     pagecountHolder = document.createElement('div');
                     pagecountHolder.id = 'page-count';
                 }
-                pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                 var inject = document.getElementById('interface-buttons');
                 inject.appendChild(pagecountHolder);
             } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'volume') {
-                if (document.getElementById('master-volume-holder') == null)
-                {
+                if (document.getElementById('master-volume-holder') == null) {
                     feedbackHolder.appendChild(interfaceContext.volume.object);
                 }
             } else if (interfaceList[k].options[i].type == 'show' && interfaceList[k].options[i].name == 'comments') {
-                interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+                interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                 break;
             }
         }
     }
-    
-    $(audioHolderObject.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		feedbackHolder.appendChild(node.holder);
-	});
-	
-	//testWaitIndicator();
+
+    $(audioHolderObject.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        feedbackHolder.appendChild(node.holder);
+    });
+
+    //testWaitIndicator();
 }
 
-function interfaceSliderHolder(interfaceObject)
-{
-	this.sliders = [];
-	this.metrics = [];
-	this.id = document.getElementsByClassName("sliderCanvasDiv").length;
-	this.name = interfaceObject.name;
-	this.interfaceObject = interfaceObject;
-	this.sliderDOM = document.createElement('div');
-	this.sliderDOM.className = 'sliderCanvasDiv';
-	this.sliderDOM.id = 'sliderCanvasHolder-'+this.id;
-	
-	var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle-"+this.id;
-	if (interfaceObject.title != undefined && typeof interfaceObject.title == "string")
-	{
-		titleSpan.textContent = interfaceObject.title;
-	} else {
-		titleSpan.textContent = "Axis "+String(this.id+1);
-	}
-	pagetitle.appendChild(titleSpan);
-	this.sliderDOM.appendChild(pagetitle);
-	
-	// Create the slider box to hold the slider elements
-	this.canvas = document.createElement('div');
-	if (this.name != undefined)
-		this.canvas.id = 'slider-'+this.name;
-	else
-		this.canvas.id = 'slider-'+this.id;
-	this.canvas.setAttribute("interfaceid",this.id);
-	this.canvas.className = 'slider';
-	this.canvas.align = "left";
-	this.canvas.addEventListener('dragover',function(event){
-		event.preventDefault();
-		event.dataTransfer.effectAllowed = 'none';
-		event.dataTransfer.dropEffect = 'copy';
-		return false;
-	},false);
-	this.sliderDOM.appendChild(this.canvas);
-	
-	// Create the div to hold any scale objects
-	this.scale = document.createElement('div');
-	this.scale.className = 'sliderScale';
-	this.scale.id = 'sliderScaleHolder-'+this.id;
-	this.scale.align = 'left';
-	this.sliderDOM.appendChild(this.scale);
-	var positionScale = this.canvas.style.width.substr(0,this.canvas.style.width.length-2);
-	var offset = 50;
+function interfaceSliderHolder(interfaceObject) {
+    this.sliders = [];
+    this.metrics = [];
+    this.id = document.getElementsByClassName("sliderCanvasDiv").length;
+    this.name = interfaceObject.name;
+    this.interfaceObject = interfaceObject;
+    this.sliderDOM = document.createElement('div');
+    this.sliderDOM.className = 'sliderCanvasDiv';
+    this.sliderDOM.id = 'sliderCanvasHolder-' + this.id;
+
+    var pagetitle = document.createElement('div');
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle-" + this.id;
+    if (interfaceObject.title != undefined && typeof interfaceObject.title == "string") {
+        titleSpan.textContent = interfaceObject.title;
+    } else {
+        titleSpan.textContent = "Axis " + String(this.id + 1);
+    }
+    pagetitle.appendChild(titleSpan);
+    this.sliderDOM.appendChild(pagetitle);
+
+    // Create the slider box to hold the slider elements
+    this.canvas = document.createElement('div');
+    if (this.name != undefined)
+        this.canvas.id = 'slider-' + this.name;
+    else
+        this.canvas.id = 'slider-' + this.id;
+    this.canvas.setAttribute("interfaceid", this.id);
+    this.canvas.className = 'slider';
+    this.canvas.align = "left";
+    this.canvas.addEventListener('dragover', function (event) {
+        event.preventDefault();
+        event.dataTransfer.effectAllowed = 'none';
+        event.dataTransfer.dropEffect = 'copy';
+        return false;
+    }, false);
+    this.sliderDOM.appendChild(this.canvas);
+
+    // Create the div to hold any scale objects
+    this.scale = document.createElement('div');
+    this.scale.className = 'sliderScale';
+    this.scale.id = 'sliderScaleHolder-' + this.id;
+    this.scale.align = 'left';
+    this.sliderDOM.appendChild(this.scale);
+    var positionScale = this.canvas.style.width.substr(0, this.canvas.style.width.length - 2);
+    var offset = 50;
     var dest = document.getElementById("slider-holder").appendChild(this.sliderDOM);
-	for (var scaleObj of interfaceObject.scales)
-	{
-		var position = Number(scaleObj.position)*0.01;
-		var pixelPosition = (position*$(this.canvas).width())+offset;
-		var scaleDOM = document.createElement('span');
+    for (var scaleObj of interfaceObject.scales) {
+        var position = Number(scaleObj.position) * 0.01;
+        var pixelPosition = (position * $(this.canvas).width()) + offset;
+        var scaleDOM = document.createElement('span');
         scaleDOM.className = "ape-marker-text";
-		scaleDOM.textContent = scaleObj.text;
-        scaleDOM.setAttribute('value',position)
-		this.scale.appendChild(scaleDOM);
-		scaleDOM.style.left = Math.floor((pixelPosition-($(scaleDOM).width()/2)))+'px';
-	}
-	
-	this.createSliderObject = function(audioObject,label)
-	{
-		var trackObj = document.createElement('div');
+        scaleDOM.textContent = scaleObj.text;
+        scaleDOM.setAttribute('value', position)
+        this.scale.appendChild(scaleDOM);
+        scaleDOM.style.left = Math.floor((pixelPosition - ($(scaleDOM).width() / 2))) + 'px';
+    }
+
+    this.createSliderObject = function (audioObject, label) {
+        var trackObj = document.createElement('div');
         trackObj.align = "center";
-		trackObj.className = 'track-slider track-slider-disabled track-slider-'+audioObject.id;
-		trackObj.id = 'track-slider-'+this.id+'-'+audioObject.id;
-		trackObj.setAttribute('trackIndex',audioObject.id);
-		if (this.name != undefined) {
-			trackObj.setAttribute('interface-name',this.name);
-		} else {
-			trackObj.setAttribute('interface-name',this.id);
-		}
-		var offset = 50;
-		// Distribute it randomnly
-		var w = window.innerWidth - (offset+8)*2;
-		w = Math.random()*w;
-		w = Math.floor(w+(offset+8));
-		trackObj.style.left = w+'px';
-		this.canvas.appendChild(trackObj);
-		this.sliders.push(trackObj);
-		this.metrics.push(new metricTracker(this));
-		var labelHolder = document.createElement("span");
+        trackObj.className = 'track-slider track-slider-disabled track-slider-' + audioObject.id;
+        trackObj.id = 'track-slider-' + this.id + '-' + audioObject.id;
+        trackObj.setAttribute('trackIndex', audioObject.id);
+        if (this.name != undefined) {
+            trackObj.setAttribute('interface-name', this.name);
+        } else {
+            trackObj.setAttribute('interface-name', this.id);
+        }
+        var offset = 50;
+        // Distribute it randomnly
+        var w = window.innerWidth - (offset + 8) * 2;
+        w = Math.random() * w;
+        w = Math.floor(w + (offset + 8));
+        trackObj.style.left = w + 'px';
+        this.canvas.appendChild(trackObj);
+        this.sliders.push(trackObj);
+        this.metrics.push(new metricTracker(this));
+        var labelHolder = document.createElement("span");
         labelHolder.textContent = label;
         trackObj.appendChild(labelHolder);
         var rate = convSliderPosToRate(trackObj);
-		this.metrics[this.metrics.length-1].initialise(rate);
-        trackObj.setAttribute("slider-value",rate);
-		return trackObj;
-	};
-	
-	this.resize = function(event)
-	{
-		var width = window.innerWidth;
-		var sliderDiv = this.canvas;
-		var sliderScaleDiv = this.scale;
-		var width = $(sliderDiv).width();
+        this.metrics[this.metrics.length - 1].initialise(rate);
+        trackObj.setAttribute("slider-value", rate);
+        return trackObj;
+    };
+
+    this.resize = function (event) {
+        var width = window.innerWidth;
+        var sliderDiv = this.canvas;
+        var sliderScaleDiv = this.scale;
+        var width = $(sliderDiv).width();
         var marginsize = 50;
-		// Move sliders into new position
-		for (var index = 0; index < this.sliders.length; index++)
-		{
-			var pix = Number(this.sliders[index].getAttribute("slider-value")) * width;
-			this.sliders[index].style.left = (pix+marginsize)+'px';
-		}
-		
-		// Move scale labels
-		for (var index = 0; index < this.scale.children.length; index++)
-		{
-			var scaleObj = this.scale.children[index];
-			var position = Number(scaleObj.attributes['value'].value);
-			var pixelPosition = (position*width)+marginsize;
-			scaleObj.style.left = Math.floor((pixelPosition-($(scaleObj).width()/2)))+'px';
-		}
-	};
+        // Move sliders into new position
+        for (var index = 0; index < this.sliders.length; index++) {
+            var pix = Number(this.sliders[index].getAttribute("slider-value")) * width;
+            this.sliders[index].style.left = (pix + marginsize) + 'px';
+        }
+
+        // Move scale labels
+        for (var index = 0; index < this.scale.children.length; index++) {
+            var scaleObj = this.scale.children[index];
+            var position = Number(scaleObj.attributes['value'].value);
+            var pixelPosition = (position * width) + marginsize;
+            scaleObj.style.left = Math.floor((pixelPosition - ($(scaleObj).width() / 2))) + 'px';
+        }
+    };
 }
 
-function sliderObject(audioObject,interfaceObjects,index) {
-	// Create a new slider object;
-	this.parent = audioObject;
-	this.trackSliderObjects = [];
+function sliderObject(audioObject, interfaceObjects, index) {
+    // Create a new slider object;
+    this.parent = audioObject;
+    this.trackSliderObjects = [];
     this.label = null;
     this.playing = false;
-    switch(audioObject.specification.parent.label) {
+    switch (audioObject.specification.parent.label) {
         case "letter":
             this.label = String.fromCharCode(97 + index);
             break;
@@ -647,295 +605,277 @@
             this.label = "";
             break;
         default:
-            this.label = ""+(index+1);
+            this.label = "" + (index + 1);
             break;
     }
-	for (var i=0; i<interfaceContext.interfaceSliders.length; i++)
-	{
-		var trackObj = interfaceContext.interfaceSliders[i].createSliderObject(audioObject,this.label);
-		this.trackSliderObjects.push(trackObj);
-	}
+    for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
+        var trackObj = interfaceContext.interfaceSliders[i].createSliderObject(audioObject, this.label);
+        this.trackSliderObjects.push(trackObj);
+    }
 
-	// Onclick, switch playback to that track
-	
-	this.enable = function() {
-		if (this.parent.state == 1)
-		{
-			$(this.trackSliderObjects).each(function(i,trackObj){
-				$(trackObj).removeClass('track-slider-disabled');
-			});
-		}
-	};
-	this.updateLoading = function(progress)
-	{
-		if (progress != 100)
-		{
-			progress = String(progress);
-			progress = progress.split('.')[0];
-			this.trackSliderObjects[0].children[0].textContent = progress+'%';
-		} else {
-			this.trackSliderObjects[0].children[0].textContent = this.label;
-		}
-	};
-    this.startPlayback = function()
-    {
+    // Onclick, switch playback to that track
+
+    this.enable = function () {
+        if (this.parent.state == 1) {
+            $(this.trackSliderObjects).each(function (i, trackObj) {
+                $(trackObj).removeClass('track-slider-disabled');
+            });
+        }
+    };
+    this.updateLoading = function (progress) {
+        if (progress != 100) {
+            progress = String(progress);
+            progress = progress.split('.')[0];
+            this.trackSliderObjects[0].children[0].textContent = progress + '%';
+        } else {
+            this.trackSliderObjects[0].children[0].textContent = this.label;
+        }
+    };
+    this.startPlayback = function () {
         $('.track-slider').removeClass('track-slider-playing');
-        var name = ".track-slider-"+this.parent.id;
+        var name = ".track-slider-" + this.parent.id;
         $(name).addClass('track-slider-playing');
         $('.comment-div').removeClass('comment-box-playing');
-        $('#comment-div-'+this.parent.id).addClass('comment-box-playing');
+        $('#comment-div-' + this.parent.id).addClass('comment-box-playing');
         $('.outside-reference').removeClass('track-slider-playing');
         this.playing = true;
-        
+
         if (this.parent.specification.parent.playOne || specification.playOne) {
             $('.track-slider').addClass('track-slider-disabled');
             $('.outside-reference').addClass('track-slider-disabled');
         }
     };
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         if (this.playing) {
             this.playing = false;
-            var name = ".track-slider-"+this.parent.id;
+            var name = ".track-slider-" + this.parent.id;
             $(name).removeClass('track-slider-playing');
-            $('#comment-div-'+this.parent.id).removeClass('comment-box-playing');
+            $('#comment-div-' + this.parent.id).removeClass('comment-box-playing');
             $('.track-slider').removeClass('track-slider-disabled');
             $('.outside-reference').removeClass('track-slider-disabled');
         }
     };
-	this.exportXMLDOM = function(audioObject) {
-		// Called by the audioObject holding this element. Must be present
-		var obj = [];
-		$(this.trackSliderObjects).each(function(i,trackObj){
-			var node = storage.document.createElement('value');
-			node.setAttribute("interface-name",trackObj.getAttribute("interface-name"));
-			node.textContent = convSliderPosToRate(trackObj);
-			obj.push(node);
-		});
-		
-		return obj;
-	};
-	this.getValue = function() {
-		return convSliderPosToRate(this.trackSliderObjects[0]);
-	};
-	this.getPresentedId = function()
-	{
-		return this.label;
-	};
-	this.canMove = function()
-	{
-		return true;
-	};
-    this.error = function() {
-            // audioObject has an error!!
+    this.exportXMLDOM = function (audioObject) {
+        // Called by the audioObject holding this element. Must be present
+        var obj = [];
+        $(this.trackSliderObjects).each(function (i, trackObj) {
+            var node = storage.document.createElement('value');
+            node.setAttribute("interface-name", trackObj.getAttribute("interface-name"));
+            node.textContent = convSliderPosToRate(trackObj);
+            obj.push(node);
+        });
+
+        return obj;
+    };
+    this.getValue = function () {
+        return convSliderPosToRate(this.trackSliderObjects[0]);
+    };
+    this.getPresentedId = function () {
+        return this.label;
+    };
+    this.canMove = function () {
+        return true;
+    };
+    this.error = function () {
+        // audioObject has an error!!
         this.playback.textContent = "Error";
         $(this.playback).addClass("error-colour");
     }
 }
 
-function outsideReferenceDOM(audioObject,index,inject)
-{
-	this.parent = audioObject;
-	this.outsideReferenceHolder = document.createElement('div');
-	this.outsideReferenceHolder.id = 'outside-reference';
-	this.outsideReferenceHolder.className = 'outside-reference track-slider-disabled';
-	var outsideReferenceHolderspan = document.createElement('span');
-	outsideReferenceHolderspan.textContent = 'Reference';
-	this.outsideReferenceHolder.appendChild(outsideReferenceHolderspan);
-	this.outsideReferenceHolder.setAttribute('track-id',index);
-	
-	this.outsideReferenceHolder.onclick = function(event)
-	{
-		audioEngineContext.play(event.currentTarget.getAttribute('track-id'));
-		$('.track-slider').removeClass('track-slider-playing');
+function outsideReferenceDOM(audioObject, index, inject) {
+    this.parent = audioObject;
+    this.outsideReferenceHolder = document.createElement('div');
+    this.outsideReferenceHolder.id = 'outside-reference';
+    this.outsideReferenceHolder.className = 'outside-reference track-slider-disabled';
+    var outsideReferenceHolderspan = document.createElement('span');
+    outsideReferenceHolderspan.textContent = 'Reference';
+    this.outsideReferenceHolder.appendChild(outsideReferenceHolderspan);
+    this.outsideReferenceHolder.setAttribute('track-id', index);
+
+    this.outsideReferenceHolder.onclick = function (event) {
+        audioEngineContext.play(event.currentTarget.getAttribute('track-id'));
+        $('.track-slider').removeClass('track-slider-playing');
         $('.comment-div').removeClass('comment-box-playing');
         if (event.currentTarget.nodeName == 'DIV') {
-        	$(event.currentTarget).addClass('track-slider-playing');
+            $(event.currentTarget).addClass('track-slider-playing');
         } else {
-        	$(event.currentTarget.parentElement).addClass('track-slider-playing');
+            $(event.currentTarget.parentElement).addClass('track-slider-playing');
         }
-	};
-	inject.appendChild(this.outsideReferenceHolder);
-	this.enable = function()
-	{
-		if (this.parent.state == 1)
-		{
-			$(this.outsideReferenceHolder).removeClass('track-slider-disabled');
-		}
-	};
-	this.updateLoading = function(progress)
-	{
-		if (progress != 100)
-		{
-			progress = String(progress);
-			progress = progress.split('.')[0];
-			this.outsideReferenceHolder.firstChild.textContent = progress+'%';
-		} else {
-			this.outsideReferenceHolder.firstChild.textContent = "Play Reference";
-		}
-	};
-    this.startPlayback = function()
-    {
+    };
+    inject.appendChild(this.outsideReferenceHolder);
+    this.enable = function () {
+        if (this.parent.state == 1) {
+            $(this.outsideReferenceHolder).removeClass('track-slider-disabled');
+        }
+    };
+    this.updateLoading = function (progress) {
+        if (progress != 100) {
+            progress = String(progress);
+            progress = progress.split('.')[0];
+            this.outsideReferenceHolder.firstChild.textContent = progress + '%';
+        } else {
+            this.outsideReferenceHolder.firstChild.textContent = "Play Reference";
+        }
+    };
+    this.startPlayback = function () {
         $('.track-slider').removeClass('track-slider-playing');
         $(this.outsideReferenceHolder).addClass('track-slider-playing');
         $('.comment-div').removeClass('comment-box-playing');
     };
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         $(this.outsideReferenceHolder).removeClass('track-slider-playing');
     };
-	this.exportXMLDOM = function(audioObject)
-	{
-		return null;
-	};
-	this.getValue = function()
-	{
-		return 0;
-	};
-	this.getPresentedId = function()
-	{
-		return 'reference';
-	};
-	this.canMove = function()
-	{
-		return false;
-	};
-    this.error = function() {
-            // audioObject has an error!!
+    this.exportXMLDOM = function (audioObject) {
+        return null;
+    };
+    this.getValue = function () {
+        return 0;
+    };
+    this.getPresentedId = function () {
+        return 'reference';
+    };
+    this.canMove = function () {
+        return false;
+    };
+    this.error = function () {
+        // audioObject has an error!!
         this.outsideReferenceHolder.textContent = "Error";
         $(this.outsideReferenceHolder).addClass("error-colour");
     }
 }
 
-function buttonSubmitClick()
-{
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	// Check that the anchor and reference objects are correctly placed
-	if (interfaceContext.checkHiddenAnchor() == false) {return;}
-	if (interfaceContext.checkHiddenReference() == false) {return;}
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkFragmentsFullyPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'scalerange':
-				// Check the scale is used to its full width outlined by the node
-				var checkState = interfaceContext.checkScaleRange();
-				if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].name+" is not supported on this interface");
-				break;
-			}
+function buttonSubmitClick() {
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-   
+    // Check that the anchor and reference objects are correctly placed
+    if (interfaceContext.checkHiddenAnchor() == false) {
+        return;
+    }
+    if (interfaceContext.checkHiddenReference() == false) {
+        return;
+    }
+
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkFragmentsFullyPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale is used to its full width outlined by the node
+                    var checkState = interfaceContext.checkScaleRange();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].name + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+
     if (canContinue) {
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Warning",'You have not started the test! Please click a fragment to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-    } 
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Warning", 'You have not started the test! Please click a fragment to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function convSliderPosToRate(trackSlider)
-{
-	var slider = trackSlider.parentElement;
-	var maxPix = $(slider).width();
-	var marginsize = 50;
-	var pix = trackSlider.style.left;
-	pix = pix.substr(0,pix.length-2);
-	var rate = (pix-marginsize)/maxPix;
-	return rate;
+function convSliderPosToRate(trackSlider) {
+    var slider = trackSlider.parentElement;
+    var maxPix = $(slider).width();
+    var marginsize = 50;
+    var pix = trackSlider.style.left;
+    pix = pix.substr(0, pix.length - 2);
+    var rate = (pix - marginsize) / maxPix;
+    return rate;
 }
 
-function resizeWindow(event){
-	// Function called when the window has been resized.
-	// MANDATORY FUNCTION
-	
-	// Resize the slider objects
-	for (var i=0; i<interfaceContext.interfaceSliders.length; i++)
-	{
-		interfaceContext.interfaceSliders[i].resize(event);
-	}
+function resizeWindow(event) {
+    // Function called when the window has been resized.
+    // MANDATORY FUNCTION
+
+    // Resize the slider objects
+    for (var i = 0; i < interfaceContext.interfaceSliders.length; i++) {
+        interfaceContext.interfaceSliders[i].resize(event);
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-	
-	if (interfaceContext.interfaceSliders.length == 1)
-	{
-		// If there is only one axis, there only needs to be one metric return
-		return;
-	}
-	var audioelements = store.getElementsByTagName("audioelement");
-	for (var i=0; i<audioelements.length; i++)
-	{
-		// Have to append the metric specific nodes
-		if (pageSpecification.outsideReference == null || pageSpecification.outsideReference.id != audioelements[i].id)
-		{
-			var inject = audioelements[i].getElementsByTagName("metric");
-			if (inject.length == 0)
-			{
-				inject = storage.document.createElement("metric");
-			} else {
-				inject = inject[0];
-			}
-			for (var k=0; k<interfaceContext.interfaceSliders.length; k++)
-			{
-				var mrnodes = interfaceContext.interfaceSliders[k].metrics[i].exportXMLDOM(inject);
-				for (var j=0; j<mrnodes.length; j++)
-				{
-					var name = mrnodes[j].getAttribute("name");
-					if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved")
-					{
-						mrnodes[j].setAttribute("interface-name",interfaceContext.interfaceSliders[k].name);
-						mrnodes[j].setAttribute("interface-id",k);
-						inject.appendChild(mrnodes[j]);
-					}
-				}
-			}
-		}
-	}
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+
+    if (interfaceContext.interfaceSliders.length == 1) {
+        // If there is only one axis, there only needs to be one metric return
+        return;
+    }
+    var audioelements = store.getElementsByTagName("audioelement");
+    for (var i = 0; i < audioelements.length; i++) {
+        // Have to append the metric specific nodes
+        if (pageSpecification.outsideReference == null || pageSpecification.outsideReference.id != audioelements[i].id) {
+            var inject = audioelements[i].getElementsByTagName("metric");
+            if (inject.length == 0) {
+                inject = storage.document.createElement("metric");
+            } else {
+                inject = inject[0];
+            }
+            for (var k = 0; k < interfaceContext.interfaceSliders.length; k++) {
+                var mrnodes = interfaceContext.interfaceSliders[k].metrics[i].exportXMLDOM(inject);
+                for (var j = 0; j < mrnodes.length; j++) {
+                    var name = mrnodes[j].getAttribute("name");
+                    if (name == "elementTracker" || name == "elementTrackerFull" || name == "elementInitialPosition" || name == "elementFlagMoved") {
+                        mrnodes[j].setAttribute("interface-name", interfaceContext.interfaceSliders[k].name);
+                        mrnodes[j].setAttribute("interface-id", k);
+                        inject.appendChild(mrnodes[j]);
+                    }
+                }
+            }
+        }
+    }
+}
--- a/interfaces/blank.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/blank.js	Mon Nov 14 14:17:03 2016 +0000
@@ -7,72 +7,61 @@
 loadInterface();
 
 function loadInterface() {
-	// Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
-	// holding div's, or setting up any nodes which are present for the entire test sequence
+    // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
+    // holding div's, or setting up any nodes which are present for the entire test sequence
 };
 
-function loadTest(page)
-{
-	// Called each time a new test page is to be build. The page specification node is the only item passed in
+function loadTest(page) {
+    // Called each time a new test page is to be build. The page specification node is the only item passed in
 }
 
-function interfaceObject()
-{
-	// An example node, you can make this however you want for each audioElement.
-	// However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
-	// You attach them by calling audioObject.bindInterface( )
-	this.enable = function()
-	{
-		// This is used to tell the interface object that playback of this node is ready
-	};
-	this.updateLoading = function(progress)
-	{
-		// progress is a value from 0 to 100 indicating the current download state of media files
-	};
-    this.startPlayback = function()
-    {
+function interfaceObject() {
+    // An example node, you can make this however you want for each audioElement.
+    // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
+    // You attach them by calling audioObject.bindInterface( )
+    this.enable = function () {
+        // This is used to tell the interface object that playback of this node is ready
+    };
+    this.updateLoading = function (progress) {
+        // progress is a value from 0 to 100 indicating the current download state of media files
+    };
+    this.startPlayback = function () {
         // Called when playback has begun
     };
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         // Called when playback has stopped. This gets called even if playback never started!
     };
-	this.getValue = function()
-	{
-		// Return the current value of the object. If there is no value, return 0
-	};
-	this.getPresentedId = function()
-	{
-		// Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
-	};
-	this.canMove = function()
-	{
-		// Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
-		// These are checked primarily if the interface check option 'fragmentMoved' is enabled.
-	};
-	this.exportXMLDOM = function(audioObject) {
-		// Called by the audioObject holding this element to export the interface <value> node.
-		// If there is no value node (such as outside reference), return null
-		// If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
-		// Use storage.document.createElement('value'); to generate the XML node.
-		
-	};
-    this.error = function() {
+    this.getValue = function () {
+        // Return the current value of the object. If there is no value, return 0
+    };
+    this.getPresentedId = function () {
+        // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
+    };
+    this.canMove = function () {
+        // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
+        // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
+    };
+    this.exportXMLDOM = function (audioObject) {
+        // Called by the audioObject holding this element to export the interface <value> node.
+        // If there is no value node (such as outside reference), return null
+        // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
+        // Use storage.document.createElement('value'); to generate the XML node.
+
+    };
+    this.error = function () {
         // If there is an error with the audioObject, this will be called to indicate a failure
     }
 };
 
-function resizeWindow(event)
-{
-	// Called on every window resize event, use this to scale your page properly
+function resizeWindow(event) {
+    // Called on every window resize event, use this to scale your page properly
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+}
--- a/interfaces/discrete.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/discrete.css	Mon Nov 14 14:17:03 2016 +0000
@@ -2,113 +2,97 @@
  * Hold any style information for MUSHRA interface. Customise if you like to make the interface your own!
  * 
  */
+
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #ddd
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #ddd
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin: 10px 0px;
+    width: auto;
+    height: 20px;
+    margin: 10px 0px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 div#slider-holder {
-	height: inherit;
-	position: absolute;
-	left: 0px;
-	z-index: 3;
-	margin-top:25px;
+    height: inherit;
+    position: absolute;
+    left: 0px;
+    z-index: 3;
+    margin-top: 25px;
 }
-
 div#scale-holder {
-	position: absolute;
-	left: 0px;
-	z-index: 2;
+    position: absolute;
+    left: 0px;
+    z-index: 2;
 }
-
 div#scale-text-holder {
-	position:relative;
-	float: left;
+    position: relative;
+    float: left;
 }
 div.scale-text {
-	position: absolute;
-	font-size: 1.2em;
+    position: absolute;
+    font-size: 1.2em;
 }
-
 canvas#scale-canvas {
-	position: relative;
-	float: left;
+    position: relative;
+    float: left;
 }
-
 div.track-slider {
-	float: left;
-	height: 30px;
-	border: solid;
-	border-width: 1px;
-	border-color: black;
-	padding:2px;
-	margin-left: 94px;
-	margin-bottom: 30px;
+    float: left;
+    height: 30px;
+    border: solid;
+    border-width: 1px;
+    border-color: black;
+    padding: 2px;
+    margin-left: 94px;
+    margin-bottom: 30px;
 }
-
 div.track-slider-range {
-	float: left;
-	height: 100%;
-	margin: 0px 50px;
-	position: relative;
+    float: left;
+    height: 100%;
+    margin: 0px 50px;
+    position: relative;
 }
-
 div.track-slider-title {
-	float: left;
-	padding-top: 5px;
-	width: 100px;
+    float: left;
+    padding-top: 5px;
+    width: 100px;
 }
-
 button.track-slider-button {
-	float: left;
-	width: 100px;
-	height: 30px;
+    float: left;
+    width: 100px;
+    height: 30px;
 }
-
 input.track-radio {
-	position: absolute;
-	margin: 9px 0px;
+    position: absolute;
+    margin: 9px 0px;
 }
-
 div#outside-reference-holder {
     display: flex;
     align-content: center;
     justify-content: center;
     margin-bottom: 5px;
 }
-
 button.outside-reference {
     position: inherit;
     margin: 0px 5px;
 }
-
 div.track-slider-playing {
-	background-color: #FFDDDD;
+    background-color: #FFDDDD;
 }
-
 div#page-count {
     float: left;
     margin: 0px 5px;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
     left: 120px;
-}
\ No newline at end of file
+}
--- a/interfaces/discrete.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/discrete.js	Mon Nov 14 14:17:03 2016 +0000
@@ -2,170 +2,166 @@
 loadInterface();
 
 function loadInterface() {
-	// Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
-	// holding div's, or setting up any nodes which are present for the entire test sequence
-	
-	// The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	testContent.id = 'testContent';
-	
-	// Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
+    // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
+    // holding div's, or setting up any nodes which are present for the entire test sequence
+
+    // The injection point into the HTML page
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+    testContent.id = 'testContent';
+
+    // Create the top div for the Title element
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
     titleSpan.id = "test-title";
-	
-	// Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-	
-	var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle";
-	pagetitle.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	interfaceButtons.style.height = '25px';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	playback.style.float = 'left';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+
+    // Set title to that defined in XML, else set to default
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
+    var pagetitle = document.createElement('div');
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle";
+    pagetitle.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+    interfaceButtons.style.height = '25px';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    playback.style.float = 'left';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-    
+        }
+    };
+
     // Create outside reference holder
     var outsideRef = document.createElement("div");
     outsideRef.id = "outside-reference-holder";
-    
-	// Create Submit (save) button
-	var submit = document.createElement("button");
-	submit.innerHTML = 'Next';
-	submit.onclick = buttonSubmitClick;
-	submit.id = 'submit-button';
-	submit.style.float = 'left';
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	interfaceButtons.appendChild(submit);
-	
-	// Create a slider box
-	var sliderBox = document.createElement('div');
-	sliderBox.style.width = "100%";
-	sliderBox.style.height = window.innerHeight - 200+12 + 'px';
-	sliderBox.style.marginBottom = '10px';
-	sliderBox.id = 'slider';
-	var scaleHolder = document.createElement('div');
-	scaleHolder.id = "scale-holder";
-	scaleHolder.style.marginLeft = "107px";
-	sliderBox.appendChild(scaleHolder);
-	var scaleText = document.createElement('div');
-	scaleText.id = "scale-text-holder";
-	scaleText.style.height = "25px";
-	scaleText.style.width = "100%";
-	scaleHolder.appendChild(scaleText);
-	var scaleCanvas = document.createElement('canvas');
-	scaleCanvas.id = "scale-canvas";
-	scaleCanvas.style.marginLeft = "150px";
-	scaleHolder.appendChild(scaleCanvas);
-	var sliderObjectHolder = document.createElement('div');
-	sliderObjectHolder.id = 'slider-holder';
-	sliderObjectHolder.align = "center";
-	sliderBox.appendChild(sliderObjectHolder);
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-	
-	testContent.style.zIndex = 1;
-	interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(pagetitle);
-	testContent.appendChild(interfaceButtons);
+
+    // Create Submit (save) button
+    var submit = document.createElement("button");
+    submit.innerHTML = 'Next';
+    submit.onclick = buttonSubmitClick;
+    submit.id = 'submit-button';
+    submit.style.float = 'left';
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+    interfaceButtons.appendChild(submit);
+
+    // Create a slider box
+    var sliderBox = document.createElement('div');
+    sliderBox.style.width = "100%";
+    sliderBox.style.height = window.innerHeight - 200 + 12 + 'px';
+    sliderBox.style.marginBottom = '10px';
+    sliderBox.id = 'slider';
+    var scaleHolder = document.createElement('div');
+    scaleHolder.id = "scale-holder";
+    scaleHolder.style.marginLeft = "107px";
+    sliderBox.appendChild(scaleHolder);
+    var scaleText = document.createElement('div');
+    scaleText.id = "scale-text-holder";
+    scaleText.style.height = "25px";
+    scaleText.style.width = "100%";
+    scaleHolder.appendChild(scaleText);
+    var scaleCanvas = document.createElement('canvas');
+    scaleCanvas.id = "scale-canvas";
+    scaleCanvas.style.marginLeft = "150px";
+    scaleHolder.appendChild(scaleCanvas);
+    var sliderObjectHolder = document.createElement('div');
+    sliderObjectHolder.id = 'slider-holder';
+    sliderObjectHolder.align = "center";
+    sliderBox.appendChild(sliderObjectHolder);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
+    testContent.style.zIndex = 1;
+    interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(pagetitle);
+    testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
-	testContent.appendChild(sliderBox);
-	testContent.appendChild(feedbackHolder);
-	interfaceContext.insertPoint.appendChild(testContent);
+    testContent.appendChild(sliderBox);
+    testContent.appendChild(feedbackHolder);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
 };
 
-function loadTest(page)
-{
-	// Called each time a new test page is to be build. The page specification node is the only item passed in
-	var id = page.id;
-	
-	var feedbackHolder = document.getElementById('feedbackHolder');
+function loadTest(page) {
+    // Called each time a new test page is to be build. The page specification node is the only item passed in
+    var id = page.id;
+
+    var feedbackHolder = document.getElementById('feedbackHolder');
     feedbackHolder.innerHTML = "";
-	var interfaceObj = page.interfaces;
-	if (interfaceObj.length > 1)
-	{
-		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
-	}
-	interfaceObj = interfaceObj[0];
-    
+    var interfaceObj = page.interfaces;
+    if (interfaceObj.length > 1) {
+        console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+    }
+    interfaceObj = interfaceObj[0];
+
     // Set the page title
     if (typeof page.title == "string" && page.title.length > 0) {
         document.getElementById("test-title").textContent = page.title
     }
-    
-	if(interfaceObj.title != null)
-	{
-		document.getElementById("pageTitle").textContent = interfaceObj.title;
-	}
-	
-	// Delete outside reference
+
+    if (interfaceObj.title != null) {
+        document.getElementById("pageTitle").textContent = interfaceObj.title;
+    }
+
+    // Delete outside reference
     document.getElementById("outside-reference-holder").innerHTML = "";
-	
-	var sliderBox = document.getElementById('slider-holder');
-	sliderBox.innerHTML = "";
-	
-	var commentBoxPrefix = "Comment on track";
-	if (interfaceObj.commentBoxPrefix != undefined) {
-		commentBoxPrefix = interfaceObj.commentBoxPrefix;
-	}
-	var loopPlayback = page.loop;
-	
-	// Find all the audioElements from the audioHolder
-	var index = 0;
-	var interfaceScales = testState.currentStateMap.interfaces[0].scales;
-	$(page.audioElements).each(function(index,element){
-		// Find URL of track
-		// In this jQuery loop, variable 'this' holds the current audioElement.
-		
-		var audioObject = audioEngineContext.newTrack(element);
-		if (element.type == 'outside-reference')
-		{
-			// Construct outside reference;
-			var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder"));
-			audioObject.bindInterface(orNode);
-		} else {
-			// Create a slider per track
-            switch(audioObject.specification.parent.label) {
+
+    var sliderBox = document.getElementById('slider-holder');
+    sliderBox.innerHTML = "";
+
+    var commentBoxPrefix = "Comment on track";
+    if (interfaceObj.commentBoxPrefix != undefined) {
+        commentBoxPrefix = interfaceObj.commentBoxPrefix;
+    }
+    var loopPlayback = page.loop;
+
+    // Find all the audioElements from the audioHolder
+    var index = 0;
+    var interfaceScales = testState.currentStateMap.interfaces[0].scales;
+    $(page.audioElements).each(function (index, element) {
+        // Find URL of track
+        // In this jQuery loop, variable 'this' holds the current audioElement.
+
+        var audioObject = audioEngineContext.newTrack(element);
+        if (element.type == 'outside-reference') {
+            // Construct outside reference;
+            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+            audioObject.bindInterface(orNode);
+        } else {
+            // Create a slider per track
+            switch (audioObject.specification.parent.label) {
                 case "none":
                     label = "";
                     break;
@@ -176,28 +172,25 @@
                     label = String.fromCharCode(65 + index);
                     break;
                 default:
-                    label = ""+index;
+                    label = "" + index;
                     break;
             }
-			var sliderObj = new discreteObject(audioObject,label,interfaceScales);
-			sliderBox.appendChild(sliderObj.holder);
-			audioObject.bindInterface(sliderObj);
+            var sliderObj = new discreteObject(audioObject, label, interfaceScales);
+            sliderBox.appendChild(sliderObj.holder);
+            audioObject.bindInterface(sliderObj);
             interfaceContext.commentBoxes.createCommentBox(audioObject);
-			index += 1;
-		}
-        
-	});
-	
+            index += 1;
+        }
+
+    });
+
     var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
-    for (var option of interfaceOptions)
-    {
-        if (option.type == "show")
-        {
-            switch(option.name) {
+    for (var option of interfaceOptions) {
+        if (option.type == "show") {
+            switch (option.name) {
                 case "playhead":
                     var playbackHolder = document.getElementById('playback-holder');
-                    if (playbackHolder == null)
-                    {
+                    if (playbackHolder == null) {
                         playbackHolder = document.createElement('div');
                         playbackHolder.style.width = "100%";
                         playbackHolder.align = 'center';
@@ -207,350 +200,341 @@
                     break;
                 case "page-count":
                     var pagecountHolder = document.getElementById('page-count');
-                    if (pagecountHolder == null)
-                    {
+                    if (pagecountHolder == null) {
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
                 case "volume":
-                    if (document.getElementById('master-volume-holder') == null)
-                    {
+                    if (document.getElementById('master-volume-holder') == null) {
                         feedbackHolder.appendChild(interfaceContext.volume.object);
                     }
                     break;
                 case "comments":
-                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
             }
         }
     }
-    
-    $(page.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		feedbackHolder.appendChild(node.holder);
-	});
-    
-	// Auto-align
-	resizeWindow(null);
+
+    $(page.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        feedbackHolder.appendChild(node.holder);
+    });
+
+    // Auto-align
+    resizeWindow(null);
 }
 
-function discreteObject(audioObject,label,interfaceScales)
-{
-	// An example node, you can make this however you want for each audioElement.
-	// However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
-	// You attach them by calling audioObject.bindInterface( )
-	if (interfaceScales == null || interfaceScales.length == 0)
-	{
-		console.log("WARNING: The discrete radio's are built depending on the number of scale points specified! Ensure you have some specified. Defaulting to 5 for now!");
-		numOptions = 5;
-	}
-	this.parent = audioObject;
-	
-	this.holder = document.createElement('div');
-	this.title = document.createElement('div');
-	this.discreteHolder = document.createElement('div');
-	this.discretes = [];
-	this.play = document.createElement('button');
-	
-	this.holder.className = 'track-slider';
-	this.holder.style.width = window.innerWidth-200 + 'px';
-	this.holder.appendChild(this.title);
-	this.holder.appendChild(this.discreteHolder);
-	this.holder.appendChild(this.play);
-	this.holder.setAttribute('trackIndex',audioObject.id);
-	this.title.textContent = label;
-	this.title.className = 'track-slider-title';
-	
-	this.discreteHolder.className = "track-slider-range";
-	this.discreteHolder.style.width = window.innerWidth-500 + 'px';
-	for (var i=0; i<interfaceScales.length; i++)
-	{
-		var node = document.createElement('input');
-		node.setAttribute('type','radio');
-		node.className = 'track-radio';
+function discreteObject(audioObject, label, interfaceScales) {
+    // An example node, you can make this however you want for each audioElement.
+    // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
+    // You attach them by calling audioObject.bindInterface( )
+    if (interfaceScales == null || interfaceScales.length == 0) {
+        console.log("WARNING: The discrete radio's are built depending on the number of scale points specified! Ensure you have some specified. Defaulting to 5 for now!");
+        numOptions = 5;
+    }
+    this.parent = audioObject;
+
+    this.holder = document.createElement('div');
+    this.title = document.createElement('div');
+    this.discreteHolder = document.createElement('div');
+    this.discretes = [];
+    this.play = document.createElement('button');
+
+    this.holder.className = 'track-slider';
+    this.holder.style.width = window.innerWidth - 200 + 'px';
+    this.holder.appendChild(this.title);
+    this.holder.appendChild(this.discreteHolder);
+    this.holder.appendChild(this.play);
+    this.holder.setAttribute('trackIndex', audioObject.id);
+    this.title.textContent = label;
+    this.title.className = 'track-slider-title';
+
+    this.discreteHolder.className = "track-slider-range";
+    this.discreteHolder.style.width = window.innerWidth - 500 + 'px';
+    for (var i = 0; i < interfaceScales.length; i++) {
+        var node = document.createElement('input');
+        node.setAttribute('type', 'radio');
+        node.className = 'track-radio';
         node.disabled = true;
-		node.setAttribute('position',interfaceScales[i].position);
-		node.setAttribute('name',audioObject.specification.id);
-		node.setAttribute('id',audioObject.specification.id+'-'+String(i));
-		this.discretes.push(node);
-		this.discreteHolder.appendChild(node);
-		node.onclick = function(event)
-		{
-			if (audioEngineContext.status == 0)
-			{
-				event.currentTarget.checked = false;
-				return;
-			}
-			var time = audioEngineContext.timer.getTestTime();
-			var id = Number(event.currentTarget.parentNode.parentNode.getAttribute('trackIndex'));
-			var value = event.currentTarget.getAttribute('position') / 100.0;
-			audioEngineContext.audioObjects[id].metric.moved(time,value);
-			console.log('slider '+id+' moved to '+value+' ('+time+')');
-		};
-	}
-	
-	this.play.className = 'track-slider-button';
-	this.play.textContent = "Loading...";
-	this.play.value = audioObject.id;
-	this.play.disabled = true;
-    this.play.setAttribute("playstate","ready");
-	this.play.onclick = function(event)
-	{
-		var id = Number(event.currentTarget.value);
-		//audioEngineContext.metric.sliderPlayed(id);
+        node.setAttribute('position', interfaceScales[i].position);
+        node.setAttribute('name', audioObject.specification.id);
+        node.setAttribute('id', audioObject.specification.id + '-' + String(i));
+        this.discretes.push(node);
+        this.discreteHolder.appendChild(node);
+        node.onclick = function (event) {
+            if (audioEngineContext.status == 0) {
+                event.currentTarget.checked = false;
+                return;
+            }
+            var time = audioEngineContext.timer.getTestTime();
+            var id = Number(event.currentTarget.parentNode.parentNode.getAttribute('trackIndex'));
+            var value = event.currentTarget.getAttribute('position') / 100.0;
+            audioEngineContext.audioObjects[id].metric.moved(time, value);
+            console.log('slider ' + id + ' moved to ' + value + ' (' + time + ')');
+        };
+    }
+
+    this.play.className = 'track-slider-button';
+    this.play.textContent = "Loading...";
+    this.play.value = audioObject.id;
+    this.play.disabled = true;
+    this.play.setAttribute("playstate", "ready");
+    this.play.onclick = function (event) {
+        var id = Number(event.currentTarget.value);
+        //audioEngineContext.metric.sliderPlayed(id);
         if (event.currentTarget.getAttribute("playstate") == "ready")
             audioEngineContext.play(id);
         else if (event.currentTarget.getAttribute("playstate") == "playing")
             audioEngineContext.stop();
-	};
-	this.resize = function(event)
-	{
-		this.holder.style.width = window.innerWidth-200 + 'px';
-		this.discreteHolder.style.width = window.innerWidth-500 + 'px';
-		//text.style.left = (posPix+150-($(text).width()/2)) +'px';
-		for (var i=0; i<this.discretes.length; i++)
-		{
-			var width = $(this.discreteHolder).width() - 20;
-			var node = this.discretes[i];
-			var nodeW = $(node).width();
-			var position = node.getAttribute('position');
-			var posPix = Math.round(width * (position / 100.0));
-			node.style.left = (posPix+10 - (nodeW/2)) + 'px';
-		}
-	};
-	this.enable = function()
-	{
-		// This is used to tell the interface object that playback of this node is ready
-		this.play.disabled = false;
-		this.play.textContent = "Play";
-		$(this.slider).removeClass('track-slider-disabled');
-        for (var radio of this.discretes)
-        {
+    };
+    this.resize = function (event) {
+        this.holder.style.width = window.innerWidth - 200 + 'px';
+        this.discreteHolder.style.width = window.innerWidth - 500 + 'px';
+        //text.style.left = (posPix+150-($(text).width()/2)) +'px';
+        for (var i = 0; i < this.discretes.length; i++) {
+            var width = $(this.discreteHolder).width() - 20;
+            var node = this.discretes[i];
+            var nodeW = $(node).width();
+            var position = node.getAttribute('position');
+            var posPix = Math.round(width * (position / 100.0));
+            node.style.left = (posPix + 10 - (nodeW / 2)) + 'px';
+        }
+    };
+    this.enable = function () {
+        // This is used to tell the interface object that playback of this node is ready
+        this.play.disabled = false;
+        this.play.textContent = "Play";
+        $(this.slider).removeClass('track-slider-disabled');
+        for (var radio of this.discretes) {
             radio.disabled = false;
         }
-	};
-	this.updateLoading = function(progress)
-	{
-		// progress is a value from 0 to 100 indicating the current download state of media files
-        if (progress != 100)
-        {
+    };
+    this.updateLoading = function (progress) {
+        // progress is a value from 0 to 100 indicating the current download state of media files
+        if (progress != 100) {
             progress = String(progress);
             progress = progress.split('.')[0];
-            this.play.textContent = progress+'%';
+            this.play.textContent = progress + '%';
         } else {
             this.play.textContent = "Play";
         }
-	};
-    
-    this.startPlayback = function()
-    {
+    };
+
+    this.startPlayback = function () {
         // Called by audioObject when playback begins
-        this.play.setAttribute("playstate","playing");
+        this.play.setAttribute("playstate", "playing");
         $(".track-slider").removeClass('track-slider-playing');
-		$(this.holder).addClass('track-slider-playing');
-		var outsideReference = document.getElementById('outside-reference');
+        $(this.holder).addClass('track-slider-playing');
+        var outsideReference = document.getElementById('outside-reference');
         this.play.textContent = "Listening";
-		if (outsideReference != null) {
-			$(outsideReference).removeClass('track-slider-playing');
-		}
+        if (outsideReference != null) {
+            $(outsideReference).removeClass('track-slider-playing');
+        }
         if (this.parent.specification.parent.playOne || specification.playOne) {
             $('.track-slider-button').text = "Wait";
-            $('.track-slider-button').attr("disabled","true");
+            $('.track-slider-button').attr("disabled", "true");
         }
     }
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         // Called by audioObject when playback stops
         if (this.play.getAttribute("playstate") == "playing") {
-            this.play.setAttribute("playstate","ready");
+            this.play.setAttribute("playstate", "ready");
             $(this.holder).removeClass('track-slider-playing');
             $('.track-slider-button').text = "Play";
             this.play.textContent = "Play";
             $('.track-slider-button').removeAttr("disabled");
         }
     }
-    
-	this.getValue = function()
-	{
-		// Return the current value of the object. If there is no value, return -1
-		var value = -1;
-		for (var i=0; i<this.discretes.length; i++)
-		{
-			if (this.discretes[i].checked == true)
-			{
-				value = this.discretes[i].getAttribute('position') / 100.0;
-				break;
-			}
-		}
-		return value;
-	};
-	this.getPresentedId = function()
-	{
-		// Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
-		return this.title.textContent;
-	};
-	this.canMove = function()
-	{
-		// Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
-		// These are checked primarily if the interface check option 'fragmentMoved' is enabled.
-		return true;
-	};
-	this.exportXMLDOM = function(audioObject) {
-		// Called by the audioObject holding this element to export the interface <value> node.
-		// If there is no value node (such as outside reference), return null
-		// If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
-		// Use storage.document.createElement('value'); to generate the XML node.
-		var node = storage.document.createElement('value');
-		node.textContent = this.getValue();
-		return node;
-	};
-    this.error = function() {
-            // audioObject has an error!!
+
+    this.getValue = function () {
+        // Return the current value of the object. If there is no value, return -1
+        var value = -1;
+        for (var i = 0; i < this.discretes.length; i++) {
+            if (this.discretes[i].checked == true) {
+                value = this.discretes[i].getAttribute('position') / 100.0;
+                break;
+            }
+        }
+        return value;
+    };
+    this.getPresentedId = function () {
+        // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
+        return this.title.textContent;
+    };
+    this.canMove = function () {
+        // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
+        // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
+        return true;
+    };
+    this.exportXMLDOM = function (audioObject) {
+        // Called by the audioObject holding this element to export the interface <value> node.
+        // If there is no value node (such as outside reference), return null
+        // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
+        // Use storage.document.createElement('value'); to generate the XML node.
+        var node = storage.document.createElement('value');
+        node.textContent = this.getValue();
+        return node;
+    };
+    this.error = function () {
+        // audioObject has an error!!
         this.playback.textContent = "Error";
         $(this.playback).addClass("error-colour");
     }
 };
 
-function resizeWindow(event)
-{
-	// Called on every window resize event, use this to scale your page properly
-	var numObj = document.getElementsByClassName('track-slider').length;
-	var totalHeight = (numObj * 66)-30;
-	document.getElementById('scale-holder').style.width = window.innerWidth-220 + 'px';
-	// Cheers edge for making me delete a canvas every resize.
-	var canvas = document.getElementById('scale-canvas');
+function resizeWindow(event) {
+    // Called on every window resize event, use this to scale your page properly
+    var numObj = document.getElementsByClassName('track-slider').length;
+    var totalHeight = (numObj * 66) - 30;
+    document.getElementById('scale-holder').style.width = window.innerWidth - 220 + 'px';
+    // Cheers edge for making me delete a canvas every resize.
+    var canvas = document.getElementById('scale-canvas');
     var new_canvas = document.createElement("canvas");
     new_canvas.id = 'scale-canvas';
     new_canvas.style.marginLeft = "150px";
     canvas.parentElement.appendChild(new_canvas);
     canvas.parentElement.removeChild(canvas);
-	new_canvas.width = window.innerWidth-520;
-	new_canvas.height = totalHeight;
-	for (var i in audioEngineContext.audioObjects)
-	{
-		if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){
-			audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
-		}
-	}
+    new_canvas.width = window.innerWidth - 520;
+    new_canvas.height = totalHeight;
+    for (var i in audioEngineContext.audioObjects) {
+        if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') {
+            audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
+        }
+    }
     document.getElementById('slider-holder').style.height = totalHeight + 'px';
     document.getElementById('slider').style.height = totalHeight + 70 + 'px';
-	drawScale();
+    drawScale();
 }
 
-function drawScale()
-{
-	var interfaceObj = testState.currentStateMap.interfaces[0];
-	var scales = testState.currentStateMap.interfaces[0].scales;
-	scales = scales.sort(function(a,b) {
-		return a.position - b.position;
-	});
-	var canvas = document.getElementById('scale-canvas');
-	var ctx = canvas.getContext("2d");
-	var height = canvas.height;
-	var width = canvas.width;
-	var textHolder = document.getElementById('scale-text-holder');
-	textHolder.innerHTML = "";
-	ctx.fillStyle = "#000000";
-	ctx.setLineDash([1,4]);
-	for (var scale of scales)
-	{
-		var posPercent = scale.position / 100.0;
-		var posPix = Math.round(width * posPercent);
-		if(posPix<=0){posPix=1;}
-		if(posPix>=width){posPix=width-1;}
-		ctx.moveTo(posPix,0);
-		ctx.lineTo(posPix,height);
-		ctx.stroke();
-		
-		var text = document.createElement('div');
-		text.align = "center";
-		var textC = document.createElement('span');
-		textC.textContent = scale.text;
-		text.appendChild(textC);
-		text.className = "scale-text";
-		textHolder.appendChild(text);
-		text.style.width = $(text.children[0]).width()+'px';
-		text.style.left = (posPix+150-($(text).width()/2)) +'px';
-	}
+function drawScale() {
+    var interfaceObj = testState.currentStateMap.interfaces[0];
+    var scales = testState.currentStateMap.interfaces[0].scales;
+    scales = scales.sort(function (a, b) {
+        return a.position - b.position;
+    });
+    var canvas = document.getElementById('scale-canvas');
+    var ctx = canvas.getContext("2d");
+    var height = canvas.height;
+    var width = canvas.width;
+    var textHolder = document.getElementById('scale-text-holder');
+    textHolder.innerHTML = "";
+    ctx.fillStyle = "#000000";
+    ctx.setLineDash([1, 4]);
+    for (var scale of scales) {
+        var posPercent = scale.position / 100.0;
+        var posPix = Math.round(width * posPercent);
+        if (posPix <= 0) {
+            posPix = 1;
+        }
+        if (posPix >= width) {
+            posPix = width - 1;
+        }
+        ctx.moveTo(posPix, 0);
+        ctx.lineTo(posPix, height);
+        ctx.stroke();
+
+        var text = document.createElement('div');
+        text.align = "center";
+        var textC = document.createElement('span');
+        textC.textContent = scale.text;
+        text.appendChild(textC);
+        text.className = "scale-text";
+        textHolder.appendChild(text);
+        text.style.width = $(text.children[0]).width() + 'px';
+        text.style.left = (posPix + 150 - ($(text).width() / 2)) + 'px';
+    }
 }
 
 function buttonSubmitClick() // TODO: Only when all songs have been played!
 {
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	// Check that the anchor and reference objects are correctly placed
-	if (interfaceContext.checkHiddenAnchor() == false) {return;}
-	if (interfaceContext.checkHiddenReference() == false) {return;}
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'scalerange':
-                // Check the scale has been used effectively
-                var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max);
-                if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
-				break;
-			}
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-	
+    // Check that the anchor and reference objects are correctly placed
+    if (interfaceContext.checkHiddenAnchor() == false) {
+        return;
+    }
+    if (interfaceContext.checkHiddenReference() == false) {
+        return;
+    }
+
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale has been used effectively
+                    var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+
     if (canContinue) {
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Warning",'You have not started the test! Please press start to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-    } 
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Warning", 'You have not started the test! Please press start to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+}
--- a/interfaces/horizontal-sliders.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/horizontal-sliders.css	Mon Nov 14 14:17:03 2016 +0000
@@ -2,137 +2,116 @@
  * Hold any style information for MUSHRA interface. Customise if you like to make the interface your own!
  * 
  */
+
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #ddd
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #ddd
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin: 10px 0px;
+    width: auto;
+    height: 20px;
+    margin: 10px 0px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 div#slider-holder {
-	height: inherit;
-	position: absolute;
-	left: 0px;
-	z-index: 3;
-	margin-top:25px;
+    height: inherit;
+    position: absolute;
+    left: 0px;
+    z-index: 3;
+    margin-top: 25px;
 }
-
 div#scale-holder {
-	height: inherit;
-	position: absolute;
-	left: 0px;
-	z-index: 2;
+    height: inherit;
+    position: absolute;
+    left: 0px;
+    z-index: 2;
 }
-
 div#scale-text-holder {
-	position:relative;
-	float: left;
+    position: relative;
+    float: left;
 }
 div.scale-text {
-	position: absolute;
-	font-size: 1.2em;
+    position: absolute;
+    font-size: 1.2em;
 }
-
 canvas#scale-canvas {
-	position: relative;
-	float: left;
+    position: relative;
+    float: left;
 }
-
 div.track-slider {
-	float: left;
-	height: 94px;
-	border: solid;
-	border-width: 1px;
-	border-color: black;
-	padding:2px;
-	margin-left: 94px;
-	margin-bottom: 25px;
+    float: left;
+    height: 94px;
+    border: solid;
+    border-width: 1px;
+    border-color: black;
+    padding: 2px;
+    margin-left: 94px;
+    margin-bottom: 25px;
 }
-
 div.track-slider-title {
-	float: left;
-	padding-top: 40px;
-	width: 100px;
+    float: left;
+    padding-top: 40px;
+    width: 100px;
 }
-
 button.track-slider-button {
-	float: left;
-	width: 100px;
-	height: 94px;
+    float: left;
+    width: 100px;
+    height: 94px;
 }
-
 div#outside-reference-holder {
     display: flex;
     align-content: center;
     justify-content: center;
     margin-bottom: 5px;
 }
-
 button.outside-reference {
     position: inherit;
     margin: 0px 5px;
 }
-
 div.track-slider-playing {
-	background-color: #FFDDDD;
+    background-color: #FFDDDD;
 }
-
 input.track-slider-range {
-	float: left;
-	margin: 2px 10px;
+    float: left;
+    margin: 2px 10px;
 }
-
-input[type=range]
-{
+input[type=range] {
     height: 94px;
     padding: 0px;
     color: rgb(255, 144, 144);
 }
-
 input[type=range]::-webkit-slider-runnable-track {
-	cursor: pointer;
-	background: #fff;
-	border-radius: 4px;
-	border: 1px solid #000;
+    cursor: pointer;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #000;
 }
-
 input[type=range]::-moz-range-track {
-	height: 8px;
-	cursor: pointer;
-	background: #fff;
-	border-radius: 4px;
-	border: 1px solid #000;
+    height: 8px;
+    cursor: pointer;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #000;
 }
-
 input.track-slider-not-moved[type=range]::-webkit-slider-runnable-track {
-	background: #aaa;
+    background: #aaa;
 }
-
 input.track-slider-not-moved[type=range]::-moz-range-track {
-	background: #aaa;
+    background: #aaa;
 }
-
 div#page-count {
     float: left;
     margin: 0px 5px;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
     left: 120px;
-}
\ No newline at end of file
+}
--- a/interfaces/horizontal-sliders.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/horizontal-sliders.js	Mon Nov 14 14:17:03 2016 +0000
@@ -2,174 +2,170 @@
 loadInterface();
 
 function loadInterface() {
-	// Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
-	// holding div's, or setting up any nodes which are present for the entire test sequence
-	
-	// The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	testContent.id = 'testContent';
-	
-	// Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
-    titleSpan.id="test-title";
-	
-	// Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-	
-	var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle";
-	pagetitle.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	interfaceButtons.style.height = '25px';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	playback.style.float = 'left';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+    // Use this to do any one-time page / element construction. For instance, placing any stationary text objects,
+    // holding div's, or setting up any nodes which are present for the entire test sequence
+
+    // The injection point into the HTML page
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+    testContent.id = 'testContent';
+
+    // Create the top div for the Title element
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "test-title";
+
+    // Set title to that defined in XML, else set to default
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
+    var pagetitle = document.createElement('div');
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle";
+    pagetitle.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+    interfaceButtons.style.height = '25px';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    playback.style.float = 'left';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-	// Create Submit (save) button
-	var submit = document.createElement("button");
-	submit.innerHTML = 'Next';
-	submit.onclick = buttonSubmitClick;
-	submit.id = 'submit-button';
-	submit.style.float = 'left';
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	interfaceButtons.appendChild(submit);
-    
+        }
+    };
+    // Create Submit (save) button
+    var submit = document.createElement("button");
+    submit.innerHTML = 'Next';
+    submit.onclick = buttonSubmitClick;
+    submit.id = 'submit-button';
+    submit.style.float = 'left';
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+    interfaceButtons.appendChild(submit);
+
     // Create outside reference holder
     var outsideRef = document.createElement("div");
     outsideRef.id = "outside-reference-holder";
-	
-	// Create a slider box
-	var sliderBox = document.createElement('div');
-	sliderBox.style.width = "100%";
-	sliderBox.style.height = window.innerHeight - 200+12 + 'px';
-	sliderBox.style.marginBottom = '10px';
-	sliderBox.id = 'slider';
-	var scaleHolder = document.createElement('div');
-	scaleHolder.id = "scale-holder";
-	scaleHolder.style.marginLeft = "107px";
-	sliderBox.appendChild(scaleHolder);
-	var scaleText = document.createElement('div');
-	scaleText.id = "scale-text-holder";
-	scaleText.style.height = "25px";
-	scaleText.style.width = "100%";
-	scaleHolder.appendChild(scaleText);
-	var scaleCanvas = document.createElement('canvas');
-	scaleCanvas.id = "scale-canvas";
-	scaleCanvas.style.marginLeft = "100px";
-	scaleHolder.appendChild(scaleCanvas);
-	var sliderObjectHolder = document.createElement('div');
-	sliderObjectHolder.id = 'slider-holder';
-	sliderObjectHolder.align = "center";
-	sliderBox.appendChild(sliderObjectHolder);
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-	
-	testContent.style.zIndex = 1;
-	interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(pagetitle);
-	testContent.appendChild(interfaceButtons);
+
+    // Create a slider box
+    var sliderBox = document.createElement('div');
+    sliderBox.style.width = "100%";
+    sliderBox.style.height = window.innerHeight - 200 + 12 + 'px';
+    sliderBox.style.marginBottom = '10px';
+    sliderBox.id = 'slider';
+    var scaleHolder = document.createElement('div');
+    scaleHolder.id = "scale-holder";
+    scaleHolder.style.marginLeft = "107px";
+    sliderBox.appendChild(scaleHolder);
+    var scaleText = document.createElement('div');
+    scaleText.id = "scale-text-holder";
+    scaleText.style.height = "25px";
+    scaleText.style.width = "100%";
+    scaleHolder.appendChild(scaleText);
+    var scaleCanvas = document.createElement('canvas');
+    scaleCanvas.id = "scale-canvas";
+    scaleCanvas.style.marginLeft = "100px";
+    scaleHolder.appendChild(scaleCanvas);
+    var sliderObjectHolder = document.createElement('div');
+    sliderObjectHolder.id = 'slider-holder';
+    sliderObjectHolder.align = "center";
+    sliderBox.appendChild(sliderObjectHolder);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
+    testContent.style.zIndex = 1;
+    interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(pagetitle);
+    testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
-	testContent.appendChild(sliderBox);
-	testContent.appendChild(feedbackHolder);
-	interfaceContext.insertPoint.appendChild(testContent);
+    testContent.appendChild(sliderBox);
+    testContent.appendChild(feedbackHolder);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
 };
 
-function loadTest(page)
-{
-	// Called each time a new test page is to be build. The page specification node is the only item passed in
-	var id = page.id;
-	
-	var feedbackHolder = document.getElementById('feedbackHolder');
+function loadTest(page) {
+    // Called each time a new test page is to be build. The page specification node is the only item passed in
+    var id = page.id;
+
+    var feedbackHolder = document.getElementById('feedbackHolder');
     feedbackHolder.innerHTML = "";
-    
-	var interfaceObj = page.interfaces;
-	if (interfaceObj.length > 1)
-	{
-		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
-	}
-	interfaceObj = interfaceObj[0];
-    
+
+    var interfaceObj = page.interfaces;
+    if (interfaceObj.length > 1) {
+        console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+    }
+    interfaceObj = interfaceObj[0];
+
     // Set the page title
     if (typeof page.title == "string" && page.title.length > 0) {
         document.getElementById("test-title").textContent = page.title
     }
-    
-	if(interfaceObj.title != null)
-	{
-		document.getElementById("pageTitle").textContent = interfaceObj.title;
-	}
-    
-	// Delete outside reference
-	document.getElementById("outside-reference-holder").innerHTML = "";
-	
-	var sliderBox = document.getElementById('slider-holder');
-	sliderBox.innerHTML = "";
-	
-	var commentBoxPrefix = "Comment on track";
-	if (interfaceObj.commentBoxPrefix != undefined) {
-		commentBoxPrefix = interfaceObj.commentBoxPrefix;
-	}
-	var loopPlayback = page.loop;
-	
-	$(page.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		feedbackHolder.appendChild(node.holder);
-	});
-	
-	// Find all the audioElements from the audioHolder
-	var index = 0;
-	$(page.audioElements).each(function(index,element){
-		// Find URL of track
-		// In this jQuery loop, variable 'this' holds the current audioElement.
-		
-		var audioObject = audioEngineContext.newTrack(element);
-		if (element.type == 'outside-reference')
-		{
-			// Construct outside reference;
-			var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,document.getElementById("outside-reference-holder"));
-			audioObject.bindInterface(orNode);
-		} else {
-			// Create a slider per track
-            switch(audioObject.specification.parent.label) {
+
+    if (interfaceObj.title != null) {
+        document.getElementById("pageTitle").textContent = interfaceObj.title;
+    }
+
+    // Delete outside reference
+    document.getElementById("outside-reference-holder").innerHTML = "";
+
+    var sliderBox = document.getElementById('slider-holder');
+    sliderBox.innerHTML = "";
+
+    var commentBoxPrefix = "Comment on track";
+    if (interfaceObj.commentBoxPrefix != undefined) {
+        commentBoxPrefix = interfaceObj.commentBoxPrefix;
+    }
+    var loopPlayback = page.loop;
+
+    $(page.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        feedbackHolder.appendChild(node.holder);
+    });
+
+    // Find all the audioElements from the audioHolder
+    var index = 0;
+    $(page.audioElements).each(function (index, element) {
+        // Find URL of track
+        // In this jQuery loop, variable 'this' holds the current audioElement.
+
+        var audioObject = audioEngineContext.newTrack(element);
+        if (element.type == 'outside-reference') {
+            // Construct outside reference;
+            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, document.getElementById("outside-reference-holder"));
+            audioObject.bindInterface(orNode);
+        } else {
+            // Create a slider per track
+            switch (audioObject.specification.parent.label) {
                 case "none":
                     label = "";
                     break;
@@ -180,36 +176,32 @@
                     label = String.fromCharCode(65 + index);
                     break;
                 default:
-                    label = ""+index;
+                    label = "" + index;
                     break;
             }
-			var sliderObj = new sliderObject(audioObject,label);
-			
-			if (typeof page.initialPosition === "number")
-			{
-				// Set the values
-				sliderObj.slider.value = page.initalPosition;
-			} else {
-				// Distribute it randomnly
-				sliderObj.slider.value = Math.random();
-			}
-			sliderBox.appendChild(sliderObj.holder);
-			audioObject.bindInterface(sliderObj);
+            var sliderObj = new sliderObject(audioObject, label);
+
+            if (typeof page.initialPosition === "number") {
+                // Set the values
+                sliderObj.slider.value = page.initalPosition;
+            } else {
+                // Distribute it randomnly
+                sliderObj.slider.value = Math.random();
+            }
+            sliderBox.appendChild(sliderObj.holder);
+            audioObject.bindInterface(sliderObj);
             interfaceContext.commentBoxes.createCommentBox(audioObject);
-			index += 1;
-		}
-        
-	});
+            index += 1;
+        }
+
+    });
     var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
-    for (var option of interfaceOptions)
-    {
-        if (option.type == "show")
-        {
-            switch(option.name) {
+    for (var option of interfaceOptions) {
+        if (option.type == "show") {
+            switch (option.name) {
                 case "playhead":
                     var playbackHolder = document.getElementById('playback-holder');
-                    if (playbackHolder == null)
-                    {
+                    if (playbackHolder == null) {
                         playbackHolder = document.createElement('div');
                         playbackHolder.style.width = "100%";
                         playbackHolder.align = 'center';
@@ -219,282 +211,282 @@
                     break;
                 case "page-count":
                     var pagecountHolder = document.getElementById('page-count');
-                    if (pagecountHolder == null)
-                    {
+                    if (pagecountHolder == null) {
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
                 case "volume":
-                    if (document.getElementById('master-volume-holder') == null)
-                    {
+                    if (document.getElementById('master-volume-holder') == null) {
                         feedbackHolder.appendChild(interfaceContext.volume.object);
                     }
                     break;
                 case "comments":
-                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
             }
         }
     }
-	// Auto-align
-	resizeWindow(null);
+    // Auto-align
+    resizeWindow(null);
 }
 
-function sliderObject(audioObject,label)
-{
-	// An example node, you can make this however you want for each audioElement.
-	// However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
-	// You attach them by calling audioObject.bindInterface( )
-	this.parent = audioObject;
-	
-	this.holder = document.createElement('div');
-	this.title = document.createElement('div');
-	this.slider = document.createElement('input');
-	this.play = document.createElement('button');
-	
-	this.holder.className = 'track-slider';
-	this.holder.style.width = window.innerWidth-200 + 'px';
-	this.holder.appendChild(this.title);
-	this.holder.appendChild(this.slider);
-	this.holder.appendChild(this.play);
-	this.holder.setAttribute('trackIndex',audioObject.id);
-	this.title.textContent = label;
-	this.title.className = 'track-slider-title';
-	
-	this.slider.type = "range";
-	this.slider.className = "track-slider-range track-slider-not-moved";
-	this.slider.min = "0";
-	this.slider.max = "1";
-	this.slider.step = "0.01";
-	this.slider.style.width = window.innerWidth-420 + 'px';
-	this.slider.onchange = function()
-	{
-		var time = audioEngineContext.timer.getTestTime();
-		var id = Number(this.parentNode.getAttribute('trackIndex'));
-		audioEngineContext.audioObjects[id].metric.moved(time,this.value);
-		console.log('slider '+id+' moved to '+this.value+' ('+time+')');
-		$(this).removeClass('track-slider-not-moved');
-	};
-	
-	this.play.className = 'track-slider-button';
-	this.play.textContent = "Loading...";
-	this.play.value = audioObject.id;
-	this.play.disabled = true;
-    this.play.setAttribute("playstate","ready");
-	this.play.onclick = function(event)
-	{
-		var id = Number(event.currentTarget.value);
-		//audioEngineContext.metric.sliderPlayed(id);
-        if (event.currentTarget.getAttribute("playstate") == "ready")
-        {audioEngineContext.play(id);}
-        else if (event.currentTarget.getAttribute("playstate") == "playing")
-        {audioEngineContext.stop();}
-	};
-	this.resize = function(event)
-	{
-		this.holder.style.width = window.innerWidth-200 + 'px';
-		this.slider.style.width = window.innerWidth-420 + 'px';
-	};
-	this.enable = function()
-	{
-		// This is used to tell the interface object that playback of this node is ready
-		this.play.disabled = false;
-		this.play.textContent = "Play";
-		$(this.slider).removeClass('track-slider-disabled');
-	};
-	this.updateLoading = function(progress)
-	{
-		// progress is a value from 0 to 100 indicating the current download state of media files
-	};
-    this.startPlayback = function()
-    {
+function sliderObject(audioObject, label) {
+    // An example node, you can make this however you want for each audioElement.
+    // However, every audioObject (audioEngineContext.audioObject) MUST have an interface object with the following
+    // You attach them by calling audioObject.bindInterface( )
+    this.parent = audioObject;
+
+    this.holder = document.createElement('div');
+    this.title = document.createElement('div');
+    this.slider = document.createElement('input');
+    this.play = document.createElement('button');
+
+    this.holder.className = 'track-slider';
+    this.holder.style.width = window.innerWidth - 200 + 'px';
+    this.holder.appendChild(this.title);
+    this.holder.appendChild(this.slider);
+    this.holder.appendChild(this.play);
+    this.holder.setAttribute('trackIndex', audioObject.id);
+    this.title.textContent = label;
+    this.title.className = 'track-slider-title';
+
+    this.slider.type = "range";
+    this.slider.className = "track-slider-range track-slider-not-moved";
+    this.slider.min = "0";
+    this.slider.max = "1";
+    this.slider.step = "0.01";
+    this.slider.style.width = window.innerWidth - 420 + 'px';
+    this.slider.onchange = function () {
+        var time = audioEngineContext.timer.getTestTime();
+        var id = Number(this.parentNode.getAttribute('trackIndex'));
+        audioEngineContext.audioObjects[id].metric.moved(time, this.value);
+        console.log('slider ' + id + ' moved to ' + this.value + ' (' + time + ')');
+        $(this).removeClass('track-slider-not-moved');
+    };
+
+    this.play.className = 'track-slider-button';
+    this.play.textContent = "Loading...";
+    this.play.value = audioObject.id;
+    this.play.disabled = true;
+    this.play.setAttribute("playstate", "ready");
+    this.play.onclick = function (event) {
+        var id = Number(event.currentTarget.value);
+        //audioEngineContext.metric.sliderPlayed(id);
+        if (event.currentTarget.getAttribute("playstate") == "ready") {
+            audioEngineContext.play(id);
+        } else if (event.currentTarget.getAttribute("playstate") == "playing") {
+            audioEngineContext.stop();
+        }
+    };
+    this.resize = function (event) {
+        this.holder.style.width = window.innerWidth - 200 + 'px';
+        this.slider.style.width = window.innerWidth - 420 + 'px';
+    };
+    this.enable = function () {
+        // This is used to tell the interface object that playback of this node is ready
+        this.play.disabled = false;
+        this.play.textContent = "Play";
+        $(this.slider).removeClass('track-slider-disabled');
+    };
+    this.updateLoading = function (progress) {
+        // progress is a value from 0 to 100 indicating the current download state of media files
+    };
+    this.startPlayback = function () {
         // Called when playback has begun
-        this.play.setAttribute("playstate","playing");
+        this.play.setAttribute("playstate", "playing");
         $(".track-slider").removeClass('track-slider-playing');
-		$(this.holder).addClass('track-slider-playing');
-		var outsideReference = document.getElementById('outside-reference');
-		if (outsideReference != null) {
-			$(outsideReference).removeClass('track-slider-playing');
-		}
+        $(this.holder).addClass('track-slider-playing');
+        var outsideReference = document.getElementById('outside-reference');
+        if (outsideReference != null) {
+            $(outsideReference).removeClass('track-slider-playing');
+        }
     };
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         // Called when playback has stopped. This gets called even if playback never started!
-        this.play.setAttribute("playstate","ready");
+        this.play.setAttribute("playstate", "ready");
         $(this.holder).removeClass('track-slider-playing');
     };
-	this.getValue = function()
-	{
-		// Return the current value of the object. If there is no value, return 0
-		return this.slider.value;
-	};
-	this.getPresentedId = function()
-	{
-		// Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
-		return this.title.textContent;
-	};
-	this.canMove = function()
-	{
-		// Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
-		// These are checked primarily if the interface check option 'fragmentMoved' is enabled.
-		return true;
-	};
-	this.exportXMLDOM = function(audioObject) {
-		// Called by the audioObject holding this element to export the interface <value> node.
-		// If there is no value node (such as outside reference), return null
-		// If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
-		// Use storage.document.createElement('value'); to generate the XML node.
-		var node = storage.document.createElement('value');
+    this.getValue = function () {
+        // Return the current value of the object. If there is no value, return 0
+        return this.slider.value;
+    };
+    this.getPresentedId = function () {
+        // Return the presented ID of the object. For instance, the APE has sliders starting from 0. Whilst AB has alphabetical scale
+        return this.title.textContent;
+    };
+    this.canMove = function () {
+        // Return either true or false if the interface object can be moved. AB / Reference cannot, whilst sliders can and therefore have a continuous scale.
+        // These are checked primarily if the interface check option 'fragmentMoved' is enabled.
+        return true;
+    };
+    this.exportXMLDOM = function (audioObject) {
+        // Called by the audioObject holding this element to export the interface <value> node.
+        // If there is no value node (such as outside reference), return null
+        // If there are multiple value nodes (such as multiple scale / 2D scales), return an array of nodes with each value node having an 'interfaceName' attribute
+        // Use storage.document.createElement('value'); to generate the XML node.
+        var node = storage.document.createElement('value');
         node.textContent = this.slider.value;
         return node;
-	};
-    this.error = function() {
-            // audioObject has an error!!
+    };
+    this.error = function () {
+        // audioObject has an error!!
         this.playback.textContent = "Error";
         $(this.playback).addClass("error-colour");
     }
 };
 
-function resizeWindow(event)
-{
-	// Called on every window resize event, use this to scale your page properly
-	
-	var numObj = document.getElementsByClassName('track-slider').length;
-	var totalHeight = (numObj * 125)-25;
-	document.getElementById('scale-holder').style.width = window.innerWidth-220 + 'px';
-	// Cheers edge for making me delete a canvas every resize.
-	var canvas = document.getElementById('scale-canvas');
+function resizeWindow(event) {
+    // Called on every window resize event, use this to scale your page properly
+
+    var numObj = document.getElementsByClassName('track-slider').length;
+    var totalHeight = (numObj * 125) - 25;
+    document.getElementById('scale-holder').style.width = window.innerWidth - 220 + 'px';
+    // Cheers edge for making me delete a canvas every resize.
+    var canvas = document.getElementById('scale-canvas');
     var new_canvas = document.createElement("canvas");
     new_canvas.id = 'scale-canvas';
     new_canvas.style.marginLeft = "100px";
     canvas.parentElement.appendChild(new_canvas);
     canvas.parentElement.removeChild(canvas);
-	new_canvas.width = window.innerWidth-420;
-	new_canvas.height = totalHeight;
-	for (var i in audioEngineContext.audioObjects)
-	{
-		if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){
-			audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
-		}
-	}
-    document.getElementById("slider").style.height = totalHeight+50+'px';
-	drawScale();
+    new_canvas.width = window.innerWidth - 420;
+    new_canvas.height = totalHeight;
+    for (var i in audioEngineContext.audioObjects) {
+        if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') {
+            audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
+        }
+    }
+    document.getElementById("slider").style.height = totalHeight + 50 + 'px';
+    drawScale();
 }
 
-function drawScale()
-{
-	var interfaceObj = testState.currentStateMap.interfaces[0];
-	var scales = testState.currentStateMap.interfaces[0].scales;
-	scales = scales.sort(function(a,b) {
-		return a.position - b.position;
-	});
-	var canvas = document.getElementById('scale-canvas');
-	var ctx = canvas.getContext("2d");
-	var height = canvas.height;
-	var width = canvas.width;
-	var textHolder = document.getElementById('scale-text-holder');
-	textHolder.innerHTML = "";
-	ctx.fillStyle = "#000000";
-	ctx.setLineDash([1,4]);
-	for (var scale of scales)
-	{
-		var posPercent = scale.position / 100.0;
-		var posPix = Math.round(width * posPercent);
-		if(posPix<=0){posPix=1;}
-		if(posPix>=width){posPix=width-1;}
-		ctx.moveTo(posPix,0);
-		ctx.lineTo(posPix,height);
-		ctx.stroke();
-		
-		var text = document.createElement('div');
-		text.align = "center";
-		var textC = document.createElement('span');
-		textC.textContent = scale.text;
-		text.appendChild(textC);
-		text.className = "scale-text";
-		textHolder.appendChild(text);
-		text.style.width = Math.ceil($(text).width())+'px';
-		text.style.left = (posPix+100-($(text).width()/2)) +'px';
-	}
+function drawScale() {
+    var interfaceObj = testState.currentStateMap.interfaces[0];
+    var scales = testState.currentStateMap.interfaces[0].scales;
+    scales = scales.sort(function (a, b) {
+        return a.position - b.position;
+    });
+    var canvas = document.getElementById('scale-canvas');
+    var ctx = canvas.getContext("2d");
+    var height = canvas.height;
+    var width = canvas.width;
+    var textHolder = document.getElementById('scale-text-holder');
+    textHolder.innerHTML = "";
+    ctx.fillStyle = "#000000";
+    ctx.setLineDash([1, 4]);
+    for (var scale of scales) {
+        var posPercent = scale.position / 100.0;
+        var posPix = Math.round(width * posPercent);
+        if (posPix <= 0) {
+            posPix = 1;
+        }
+        if (posPix >= width) {
+            posPix = width - 1;
+        }
+        ctx.moveTo(posPix, 0);
+        ctx.lineTo(posPix, height);
+        ctx.stroke();
+
+        var text = document.createElement('div');
+        text.align = "center";
+        var textC = document.createElement('span');
+        textC.textContent = scale.text;
+        text.appendChild(textC);
+        text.className = "scale-text";
+        textHolder.appendChild(text);
+        text.style.width = Math.ceil($(text).width()) + 'px';
+        text.style.left = (posPix + 100 - ($(text).width() / 2)) + 'px';
+    }
 }
 
 function buttonSubmitClick() // TODO: Only when all songs have been played!
 {
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	// Check that the anchor and reference objects are correctly placed
-	if (interfaceContext.checkHiddenAnchor() == false) {return;}
-	if (interfaceContext.checkHiddenReference() == false) {return;}
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'scalerange':
-                // Check the scale has been used effectively
-                var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max);
-                if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
-				break;
-			}
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-	
+    // Check that the anchor and reference objects are correctly placed
+    if (interfaceContext.checkHiddenAnchor() == false) {
+        return;
+    }
+    if (interfaceContext.checkHiddenReference() == false) {
+        return;
+    }
+
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale has been used effectively
+                    var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+
     if (canContinue) {
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Warning",'You have not started the test! Please press start to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-    } 
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Warning", 'You have not started the test! Please press start to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
-}
\ No newline at end of file
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
+}
--- a/interfaces/mushra.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/mushra.css	Mon Nov 14 14:17:03 2016 +0000
@@ -2,156 +2,133 @@
  * Hold any style information for MUSHRA interface. Customise if you like to make the interface your own!
  * 
  */
+
 body {
-	/* Set the background colour (note US English spelling) to grey*/
-	background-color: #ddd
+    /* Set the background colour (note US English spelling) to grey*/
+    background-color: #ddd
 }
-
 div.pageTitle {
-	width: auto;
-	height: 20px;
-	margin: 10px 0px;
+    width: auto;
+    height: 20px;
+    margin: 10px 0px;
 }
-
-div.pageTitle span{
-	font-size: 1.5em;
+div.pageTitle span {
+    font-size: 1.5em;
 }
-
 button {
-	/* Specify any button structure or style */
-	min-width: 20px;
-	background-color: #ddd
+    /* Specify any button structure or style */
+    min-width: 20px;
+    background-color: #ddd
 }
-
 div#slider-holder {
-	height: inherit;
-	position: absolute;
-	left: 0px;
-	z-index: 3;
+    height: inherit;
+    position: absolute;
+    left: 0px;
+    z-index: 3;
 }
-
 div#scale-holder {
-	height: inherit;
-	position: absolute;
-	left: 0px;
-	z-index: 2;
+    height: inherit;
+    position: absolute;
+    left: 0px;
+    z-index: 2;
 }
-
 div#scale-text-holder {
-	position:relative;
-	width: 100px;
-	float: left;
+    position: relative;
+    width: 100px;
+    float: left;
 }
 div.scale-text {
-	position: absolute;
+    position: absolute;
 }
-
 canvas#scale-canvas {
-	position: relative;
-	float: left;
+    position: relative;
+    float: left;
 }
-
 div.track-slider {
-	float: left;
-	width: 94px;
-	border: solid;
-	border-width: 1px;
-	border-color: black;
-	padding:2px;
-	margin-left: 50px;
+    float: left;
+    width: 94px;
+    border: solid;
+    border-width: 1px;
+    border-color: black;
+    padding: 2px;
+    margin-left: 50px;
 }
-
 div#outside-reference-holder {
     display: flex;
     align-content: center;
     justify-content: center;
     margin-bottom: 5px;
 }
-
 button.outside-reference {
     position: inherit;
     margin: 0px 5px;
 }
-
 div.track-slider-playing {
-	background-color: #FFDDDD;
+    background-color: #FFDDDD;
 }
-
 input.track-slider-range {
-	margin: 2px 0px;
+    margin: 2px 0px;
 }
-
-input[type=range][orient=vertical]
-{
-    writing-mode: bt-lr; /* IE */
-    -webkit-appearance: slider-vertical; /* WebKit */
+input[type=range][orient=vertical] {
+    writing-mode: bt-lr;
+    /* IE */
+    -webkit-appearance: slider-vertical;
+    /* WebKit */
     width: 8px;
     padding: 0 5px;
     color: rgb(255, 144, 144);
 }
-
 input[type=range]::-webkit-slider-runnable-track {
-	width: 8px;
-	cursor: pointer;
-	background: #fff;
-	border-radius: 4px;
-	border: 1px solid #000;
+    width: 8px;
+    cursor: pointer;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #000;
 }
-
 input[type=range]::-moz-range-track {
-	width: 8px;
-	cursor: pointer;
-	background: #fff;
-	border-radius: 4px;
-	border: 1px solid #000;
+    width: 8px;
+    cursor: pointer;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #000;
 }
-
 input[type=range]::-ms-track {
-	cursor: pointer;
-	background: #fff;
-	border-radius: 4px;
-	border: 1px solid #000;
+    cursor: pointer;
+    background: #fff;
+    border-radius: 4px;
+    border: 1px solid #000;
 }
-
 input.track-slider-not-moved[type=range]::-webkit-slider-runnable-track {
-	background: #aaa;
+    background: #aaa;
 }
-
 input.track-slider-not-moved[type=range]::-moz-range-track {
-	background: #aaa;
+    background: #aaa;
 }
-
-
 input[type=range]::-moz-range-thumb {
-	margin-left: -7px;
-	cursor: pointer;
-	margin-top: -1px;
-	box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+    margin-left: -7px;
+    cursor: pointer;
+    margin-top: -1px;
+    box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
 }
-
 input[type=range]::-webkit-slider-thumb {
-	cursor: pointer;
-	margin-top: -1px;
-	margin-left: -4px;
+    cursor: pointer;
+    margin-top: -1px;
+    margin-left: -4px;
 }
-
 input[type=range]::-ms-thumb {
-	cursor: pointer;
-	margin-top: -1px;
-	margin-left: -4px;
+    cursor: pointer;
+    margin-top: -1px;
+    margin-left: -4px;
 }
-
 input[type=range]::-ms-tooltip {
-	visibility:hidden;
+    visibility: hidden;
 }
-
 div#page-count {
     float: left;
     margin: 0px 5px;
 }
-
 div#master-volume-holder {
     position: absolute;
     top: 10px;
     left: 120px;
-}
\ No newline at end of file
+}
--- a/interfaces/mushra.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/mushra.js	Mon Nov 14 14:17:03 2016 +0000
@@ -7,170 +7,166 @@
 loadInterface();
 
 function loadInterface() {
-	// Get the dimensions of the screen available to the page
-	var width = window.innerWidth;
-	var height = window.innerHeight;
-	
-	// The injection point into the HTML page
-	interfaceContext.insertPoint = document.getElementById("topLevelBody");
-	var testContent = document.createElement('div');
-	testContent.id = 'testContent';
-	
-	// Create the top div for the Title element
-	var titleAttr = specification.title;
-	var title = document.createElement('div');
-	title.className = "title";
-	title.align = "center";
-	var titleSpan = document.createElement('span');
+    // Get the dimensions of the screen available to the page
+    var width = window.innerWidth;
+    var height = window.innerHeight;
+
+    // The injection point into the HTML page
+    interfaceContext.insertPoint = document.getElementById("topLevelBody");
+    var testContent = document.createElement('div');
+    testContent.id = 'testContent';
+
+    // Create the top div for the Title element
+    var titleAttr = specification.title;
+    var title = document.createElement('div');
+    title.className = "title";
+    title.align = "center";
+    var titleSpan = document.createElement('span');
     titleSpan.id = "test-title";
-	
-	// Set title to that defined in XML, else set to default
-	if (titleAttr != undefined) {
-		titleSpan.textContent = titleAttr;
-	} else {
-		titleSpan.textContent =  'Listening test';
-	}
-	// Insert the titleSpan element into the title div element.
-	title.appendChild(titleSpan);
-	
-	var pagetitle = document.createElement('div');
-	pagetitle.className = "pageTitle";
-	pagetitle.align = "center";
-	var titleSpan = document.createElement('span');
-	titleSpan.id = "pageTitle";
-	pagetitle.appendChild(titleSpan);
-	
-	// Create Interface buttons!
-	var interfaceButtons = document.createElement('div');
-	interfaceButtons.id = 'interface-buttons';
-	interfaceButtons.style.height = '25px';
-	
-	// Create playback start/stop points
-	var playback = document.createElement("button");
-	playback.innerHTML = 'Stop';
-	playback.id = 'playback-button';
-	playback.style.float = 'left';
-	// onclick function. Check if it is playing or not, call the correct function in the
-	// audioEngine, change the button text to reflect the next state.
-	playback.onclick = function() {
-		if (audioEngineContext.status == 1) {
-			audioEngineContext.stop();
-			this.innerHTML = 'Stop';
+
+    // Set title to that defined in XML, else set to default
+    if (titleAttr != undefined) {
+        titleSpan.textContent = titleAttr;
+    } else {
+        titleSpan.textContent = 'Listening test';
+    }
+    // Insert the titleSpan element into the title div element.
+    title.appendChild(titleSpan);
+
+    var pagetitle = document.createElement('div');
+    pagetitle.className = "pageTitle";
+    pagetitle.align = "center";
+    var titleSpan = document.createElement('span');
+    titleSpan.id = "pageTitle";
+    pagetitle.appendChild(titleSpan);
+
+    // Create Interface buttons!
+    var interfaceButtons = document.createElement('div');
+    interfaceButtons.id = 'interface-buttons';
+    interfaceButtons.style.height = '25px';
+
+    // Create playback start/stop points
+    var playback = document.createElement("button");
+    playback.innerHTML = 'Stop';
+    playback.id = 'playback-button';
+    playback.style.float = 'left';
+    // onclick function. Check if it is playing or not, call the correct function in the
+    // audioEngine, change the button text to reflect the next state.
+    playback.onclick = function () {
+        if (audioEngineContext.status == 1) {
+            audioEngineContext.stop();
+            this.innerHTML = 'Stop';
             var time = audioEngineContext.timer.getTestTime();
             console.log('Stopped at ' + time); // DEBUG/SAFETY
-		}
-	};
-	// Create Submit (save) button
-	var submit = document.createElement("button");
-	submit.innerHTML = 'Next';
-	submit.onclick = buttonSubmitClick;
-	submit.id = 'submit-button';
-	submit.style.float = 'left';
-	// Append the interface buttons into the interfaceButtons object.
-	interfaceButtons.appendChild(playback);
-	interfaceButtons.appendChild(submit);
-    
+        }
+    };
+    // Create Submit (save) button
+    var submit = document.createElement("button");
+    submit.innerHTML = 'Next';
+    submit.onclick = buttonSubmitClick;
+    submit.id = 'submit-button';
+    submit.style.float = 'left';
+    // Append the interface buttons into the interfaceButtons object.
+    interfaceButtons.appendChild(playback);
+    interfaceButtons.appendChild(submit);
+
     // Create outside reference holder
     var outsideRef = document.createElement("div");
     outsideRef.id = "outside-reference-holder";
-    
-	
-	// Create a slider box
-	var sliderBox = document.createElement('div');
-	sliderBox.style.width = "100%";
-	sliderBox.style.height = window.innerHeight - 200+12 + 'px';
-	sliderBox.style.marginBottom = '10px';
-	sliderBox.id = 'slider';
-	var scaleHolder = document.createElement('div');
-	scaleHolder.id = "scale-holder";
-	sliderBox.appendChild(scaleHolder);
-	var scaleText = document.createElement('div');
-	scaleText.id = "scale-text-holder";
-	scaleHolder.appendChild(scaleText);
-	var scaleCanvas = document.createElement('canvas');
-	scaleCanvas.id = "scale-canvas";
-	scaleHolder.appendChild(scaleCanvas);
-	var sliderObjectHolder = document.createElement('div');
-	sliderObjectHolder.id = 'slider-holder';
-	sliderObjectHolder.align = "center";
-	sliderBox.appendChild(sliderObjectHolder);
-	
-	// Global parent for the comment boxes on the page
-	var feedbackHolder = document.createElement('div');
-	feedbackHolder.id = 'feedbackHolder';
-	
-	testContent.style.zIndex = 1;
-	interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
-	
-	// Inject into HTML
-	testContent.appendChild(title); // Insert the title
-	testContent.appendChild(pagetitle);
-	testContent.appendChild(interfaceButtons);
+
+
+    // Create a slider box
+    var sliderBox = document.createElement('div');
+    sliderBox.style.width = "100%";
+    sliderBox.style.height = window.innerHeight - 200 + 12 + 'px';
+    sliderBox.style.marginBottom = '10px';
+    sliderBox.id = 'slider';
+    var scaleHolder = document.createElement('div');
+    scaleHolder.id = "scale-holder";
+    sliderBox.appendChild(scaleHolder);
+    var scaleText = document.createElement('div');
+    scaleText.id = "scale-text-holder";
+    scaleHolder.appendChild(scaleText);
+    var scaleCanvas = document.createElement('canvas');
+    scaleCanvas.id = "scale-canvas";
+    scaleHolder.appendChild(scaleCanvas);
+    var sliderObjectHolder = document.createElement('div');
+    sliderObjectHolder.id = 'slider-holder';
+    sliderObjectHolder.align = "center";
+    sliderBox.appendChild(sliderObjectHolder);
+
+    // Global parent for the comment boxes on the page
+    var feedbackHolder = document.createElement('div');
+    feedbackHolder.id = 'feedbackHolder';
+
+    testContent.style.zIndex = 1;
+    interfaceContext.insertPoint.innerHTML = ""; // Clear the current schema
+
+    // Inject into HTML
+    testContent.appendChild(title); // Insert the title
+    testContent.appendChild(pagetitle);
+    testContent.appendChild(interfaceButtons);
     testContent.appendChild(outsideRef);
-	testContent.appendChild(sliderBox);
-	testContent.appendChild(feedbackHolder);
-	interfaceContext.insertPoint.appendChild(testContent);
+    testContent.appendChild(sliderBox);
+    testContent.appendChild(feedbackHolder);
+    interfaceContext.insertPoint.appendChild(testContent);
 
-	// Load the full interface
-	testState.initialise();
-	testState.advanceState();
+    // Load the full interface
+    testState.initialise();
+    testState.advanceState();
 }
 
-function loadTest(audioHolderObject)
-{
-	var id = audioHolderObject.id;
-	
-	var feedbackHolder = document.getElementById('feedbackHolder');
+function loadTest(audioHolderObject) {
+    var id = audioHolderObject.id;
+
+    var feedbackHolder = document.getElementById('feedbackHolder');
     feedbackHolder.innerHTML = "";
-	var interfaceObj = audioHolderObject.interfaces;
-	if (interfaceObj.length > 1)
-	{
-		console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
-	}
-	interfaceObj = interfaceObj[0];
-    
+    var interfaceObj = audioHolderObject.interfaces;
+    if (interfaceObj.length > 1) {
+        console.log("WARNING - This interface only supports one <interface> node per page. Using first interface node");
+    }
+    interfaceObj = interfaceObj[0];
+
     // Set the page title
     if (typeof audioHolderObject.title == "string" && audioHolderObject.title.length > 0) {
         document.getElementById("test-title").textContent = audioHolderObject.title
     }
-    
-	if(interfaceObj.title != null)
-	{
-		document.getElementById("pageTitle").textContent = interfaceObj.title;
-	}
-	
-	// Delete outside reference
-	var outsideReferenceHolder = document.getElementById("outside-reference-holder");
+
+    if (interfaceObj.title != null) {
+        document.getElementById("pageTitle").textContent = interfaceObj.title;
+    }
+
+    // Delete outside reference
+    var outsideReferenceHolder = document.getElementById("outside-reference-holder");
     outsideReferenceHolder.innerHTML = "";
-	
-	var sliderBox = document.getElementById('slider-holder');
-	sliderBox.innerHTML = "";
-	
-	var commentBoxPrefix = "Comment on track";
-	if (interfaceObj.commentBoxPrefix != undefined) {
-		commentBoxPrefix = interfaceObj.commentBoxPrefix;
-	}
-	var loopPlayback = audioHolderObject.loop;
-	
-	currentTestHolder = document.createElement('audioHolder');
-	currentTestHolder.id = audioHolderObject.id;
-	currentTestHolder.repeatCount = audioHolderObject.repeatCount;
-	
-	// Find all the audioElements from the audioHolder
-	var index = 0;
-	$(audioHolderObject.audioElements).each(function(index,element){
-		// Find URL of track
-		// In this jQuery loop, variable 'this' holds the current audioElement.
-		
-		var audioObject = audioEngineContext.newTrack(element);
-		if (element.type == 'outside-reference')
-		{
-			// Construct outside reference;
-			var orNode = new interfaceContext.outsideReferenceDOM(audioObject,index,outsideReferenceHolder);
-			audioObject.bindInterface(orNode);
-		} else {
-			// Create a slider per track
-            switch(audioObject.specification.parent.label) {
+
+    var sliderBox = document.getElementById('slider-holder');
+    sliderBox.innerHTML = "";
+
+    var commentBoxPrefix = "Comment on track";
+    if (interfaceObj.commentBoxPrefix != undefined) {
+        commentBoxPrefix = interfaceObj.commentBoxPrefix;
+    }
+    var loopPlayback = audioHolderObject.loop;
+
+    currentTestHolder = document.createElement('audioHolder');
+    currentTestHolder.id = audioHolderObject.id;
+    currentTestHolder.repeatCount = audioHolderObject.repeatCount;
+
+    // Find all the audioElements from the audioHolder
+    var index = 0;
+    $(audioHolderObject.audioElements).each(function (index, element) {
+        // Find URL of track
+        // In this jQuery loop, variable 'this' holds the current audioElement.
+
+        var audioObject = audioEngineContext.newTrack(element);
+        if (element.type == 'outside-reference') {
+            // Construct outside reference;
+            var orNode = new interfaceContext.outsideReferenceDOM(audioObject, index, outsideReferenceHolder);
+            audioObject.bindInterface(orNode);
+        } else {
+            // Create a slider per track
+            switch (audioObject.specification.parent.label) {
                 case "none":
                     label = "";
                     break;
@@ -181,38 +177,34 @@
                     label = String.fromCharCode(65 + index);
                     break;
                 default:
-                    label = ""+index;
+                    label = "" + index;
                     break;
             }
-			var sliderObj = new sliderObject(audioObject,label);
-			
-			if (typeof audioHolderObject.initialPosition === "number")
-			{
-				// Set the values
-				sliderObj.slider.value = audioHolderObject.initalPosition;
-			} else {
-				// Distribute it randomnly
-				sliderObj.slider.value = Math.random();
-			}
-			sliderBox.appendChild(sliderObj.holder);
-			audioObject.bindInterface(sliderObj);
+            var sliderObj = new sliderObject(audioObject, label);
+
+            if (typeof audioHolderObject.initialPosition === "number") {
+                // Set the values
+                sliderObj.slider.value = audioHolderObject.initalPosition;
+            } else {
+                // Distribute it randomnly
+                sliderObj.slider.value = Math.random();
+            }
+            sliderBox.appendChild(sliderObj.holder);
+            audioObject.bindInterface(sliderObj);
             interfaceContext.commentBoxes.createCommentBox(audioObject);
-			index += 1;
-		}
-        
-	});
-    
-    
+            index += 1;
+        }
+
+    });
+
+
     var interfaceOptions = specification.interfaces.options.concat(interfaceObj.options);
-    for (var option of interfaceOptions)
-    {
-        if (option.type == "show")
-        {
-            switch(option.name) {
+    for (var option of interfaceOptions) {
+        if (option.type == "show") {
+            switch (option.name) {
                 case "playhead":
                     var playbackHolder = document.getElementById('playback-holder');
-                    if (playbackHolder == null)
-                    {
+                    if (playbackHolder == null) {
                         playbackHolder = document.createElement('div');
                         playbackHolder.style.width = "100%";
                         playbackHolder.align = 'center';
@@ -222,308 +214,305 @@
                     break;
                 case "page-count":
                     var pagecountHolder = document.getElementById('page-count');
-                    if (pagecountHolder == null)
-                    {
+                    if (pagecountHolder == null) {
                         pagecountHolder = document.createElement('div');
                         pagecountHolder.id = 'page-count';
                     }
-                    pagecountHolder.innerHTML = '<span>Page '+(testState.stateIndex+1)+' of '+testState.stateMap.length+'</span>';
+                    pagecountHolder.innerHTML = '<span>Page ' + (testState.stateIndex + 1) + ' of ' + testState.stateMap.length + '</span>';
                     var inject = document.getElementById('interface-buttons');
                     inject.appendChild(pagecountHolder);
                     break;
                 case "volume":
-                    if (document.getElementById('master-volume-holder') == null)
-                    {
+                    if (document.getElementById('master-volume-holder') == null) {
                         feedbackHolder.appendChild(interfaceContext.volume.object);
                     }
                     break;
                 case "comments":
-                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder,true);
+                    interfaceContext.commentBoxes.showCommentBoxes(feedbackHolder, true);
                     break;
             }
         }
     }
-	
-	$(audioHolderObject.commentQuestions).each(function(index,element) {
-		var node = interfaceContext.createCommentQuestion(element);
-		feedbackHolder.appendChild(node.holder);
-	});
-	
-	// Auto-align
-	resizeWindow(null);
+
+    $(audioHolderObject.commentQuestions).each(function (index, element) {
+        var node = interfaceContext.createCommentQuestion(element);
+        feedbackHolder.appendChild(node.holder);
+    });
+
+    // Auto-align
+    resizeWindow(null);
 }
 
-function sliderObject(audioObject,label)
-{
-	// Constructs the slider object. We use the HTML5 slider object
-	this.parent = audioObject;
-	this.holder = document.createElement('div');
-	this.title = document.createElement('span');
-	this.slider = document.createElement('input');
-	this.play = document.createElement('button');
-	
-	this.holder.className = 'track-slider';
-	this.holder.style.height = window.innerHeight-200 + 'px';
-	this.holder.appendChild(this.title);
-	this.holder.appendChild(this.slider);
-	this.holder.appendChild(this.play);
-	this.holder.align = "center";
-	if (label == 0)
-	{
-		this.holder.style.marginLeft = '0px';
-	}
-	this.holder.setAttribute('trackIndex',audioObject.id);
-	
-	this.title.textContent = label;
-	this.title.style.width = "100%";
-	this.title.style.float = "left";
-	
-	this.slider.type = "range";
-	this.slider.className = "track-slider-range track-slider-not-moved";
-	this.slider.min = "0";
-	this.slider.max = "1";
-	this.slider.step = "0.01";
-	this.slider.setAttribute('orient','vertical');
-	this.slider.style.height = window.innerHeight-250 + 'px';
-	this.slider.onchange = function()
-	{
-		var time = audioEngineContext.timer.getTestTime();
-		var id = Number(this.parentNode.getAttribute('trackIndex'));
-		audioEngineContext.audioObjects[id].metric.moved(time,this.value);
-		console.log('slider '+id+' moved to '+this.value+' ('+time+')');
-		$(this).removeClass('track-slider-not-moved');
-	};
-	
-	this.play.textContent = "Loading...";
-	this.play.value = audioObject.id;
-	this.play.style.float = "left";
-	this.play.style.width = "100%";
-	this.play.disabled = true;
-    this.play.setAttribute("playstate","ready");
-	this.play.onclick = function(event)
-	{
-		var id = Number(event.currentTarget.value);
-		//audioEngineContext.metric.sliderPlayed(id);
-		if (event.currentTarget.getAttribute("playstate") == "ready")
-        {audioEngineContext.play(id);}
-        else if (event.currentTarget.getAttribute("playstate") == "playing")
-        {audioEngineContext.stop();}
-	};
-	
-	this.enable = function() {
-		this.play.disabled = false;
-		this.play.textContent = "Play";
-		$(this.slider).removeClass('track-slider-disabled');
-	};
-	
-	this.exportXMLDOM = function(audioObject) {
-		// Called by the audioObject holding this element. Must be present
-		var node = storage.document.createElement('value');
-		node.textContent = this.slider.value;
-		return node;
-	};
-    this.startPlayback = function()
-    {
+function sliderObject(audioObject, label) {
+    // Constructs the slider object. We use the HTML5 slider object
+    this.parent = audioObject;
+    this.holder = document.createElement('div');
+    this.title = document.createElement('span');
+    this.slider = document.createElement('input');
+    this.play = document.createElement('button');
+
+    this.holder.className = 'track-slider';
+    this.holder.style.height = window.innerHeight - 200 + 'px';
+    this.holder.appendChild(this.title);
+    this.holder.appendChild(this.slider);
+    this.holder.appendChild(this.play);
+    this.holder.align = "center";
+    if (label == 0) {
+        this.holder.style.marginLeft = '0px';
+    }
+    this.holder.setAttribute('trackIndex', audioObject.id);
+
+    this.title.textContent = label;
+    this.title.style.width = "100%";
+    this.title.style.float = "left";
+
+    this.slider.type = "range";
+    this.slider.className = "track-slider-range track-slider-not-moved";
+    this.slider.min = "0";
+    this.slider.max = "1";
+    this.slider.step = "0.01";
+    this.slider.setAttribute('orient', 'vertical');
+    this.slider.style.height = window.innerHeight - 250 + 'px';
+    this.slider.onchange = function () {
+        var time = audioEngineContext.timer.getTestTime();
+        var id = Number(this.parentNode.getAttribute('trackIndex'));
+        audioEngineContext.audioObjects[id].metric.moved(time, this.value);
+        console.log('slider ' + id + ' moved to ' + this.value + ' (' + time + ')');
+        $(this).removeClass('track-slider-not-moved');
+    };
+
+    this.play.textContent = "Loading...";
+    this.play.value = audioObject.id;
+    this.play.style.float = "left";
+    this.play.style.width = "100%";
+    this.play.disabled = true;
+    this.play.setAttribute("playstate", "ready");
+    this.play.onclick = function (event) {
+        var id = Number(event.currentTarget.value);
+        //audioEngineContext.metric.sliderPlayed(id);
+        if (event.currentTarget.getAttribute("playstate") == "ready") {
+            audioEngineContext.play(id);
+        } else if (event.currentTarget.getAttribute("playstate") == "playing") {
+            audioEngineContext.stop();
+        }
+    };
+
+    this.enable = function () {
+        this.play.disabled = false;
+        this.play.textContent = "Play";
+        $(this.slider).removeClass('track-slider-disabled');
+    };
+
+    this.exportXMLDOM = function (audioObject) {
+        // Called by the audioObject holding this element. Must be present
+        var node = storage.document.createElement('value');
+        node.textContent = this.slider.value;
+        return node;
+    };
+    this.startPlayback = function () {
         // Called when playback has begun
-        this.play.setAttribute("playstate","playing");
+        this.play.setAttribute("playstate", "playing");
         $(".track-slider").removeClass('track-slider-playing');
-		$(this.holder).addClass('track-slider-playing');
-		var outsideReference = document.getElementById('outside-reference');
-		if (outsideReference != null) {
-			$(outsideReference).removeClass('track-slider-playing');
-		}
+        $(this.holder).addClass('track-slider-playing');
+        var outsideReference = document.getElementById('outside-reference');
+        if (outsideReference != null) {
+            $(outsideReference).removeClass('track-slider-playing');
+        }
         this.play.textContent = "Stop";
     };
-    this.stopPlayback = function()
-    {
+    this.stopPlayback = function () {
         // Called when playback has stopped. This gets called even if playback never started!
-        this.play.setAttribute("playstate","ready");
+        this.play.setAttribute("playstate", "ready");
         $(this.holder).removeClass('track-slider-playing');
         this.play.textContent = "Play";
     };
-	this.getValue = function() {
-		return this.slider.value;
-	};
-	
-	this.resize = function(event)
-	{
-		this.holder.style.height = window.innerHeight-200 + 'px';
-		this.slider.style.height = window.innerHeight-250 + 'px';
-	};
-	this.updateLoading = function(progress)
-	{
-		progress = String(progress);
-		progress = progress.substr(0,5);
-		this.play.textContent = "Loading: "+progress+"%";
-	};
-	
-	if (this.parent.state == 1)
-	{
-		this.enable();
-	}
-	this.getPresentedId = function()
-	{
-		return this.title.textContent;
-	};
-	this.canMove = function()
-	{
-		return true;
-	};
-    this.error = function() {
-            // audioObject has an error!!
+    this.getValue = function () {
+        return this.slider.value;
+    };
+
+    this.resize = function (event) {
+        this.holder.style.height = window.innerHeight - 200 + 'px';
+        this.slider.style.height = window.innerHeight - 250 + 'px';
+    };
+    this.updateLoading = function (progress) {
+        progress = String(progress);
+        progress = progress.substr(0, 5);
+        this.play.textContent = "Loading: " + progress + "%";
+    };
+
+    if (this.parent.state == 1) {
+        this.enable();
+    }
+    this.getPresentedId = function () {
+        return this.title.textContent;
+    };
+    this.canMove = function () {
+        return true;
+    };
+    this.error = function () {
+        // audioObject has an error!!
         this.playback.textContent = "Error";
         $(this.playback).addClass("error-colour");
     }
 }
 
-function resizeWindow(event)
-{
-	// Function called when the window has been resized.
-	// MANDATORY FUNCTION
-	
-	var outsideRef = document.getElementById('outside-reference');
-	if(outsideRef != null)
-	{
-		outsideRef.style.left = (window.innerWidth-120)/2 + 'px';
-	}
-	
-	// Auto-align
-	var numObj = document.getElementsByClassName('track-slider').length;
-	var totalWidth = (numObj-1)*150+100;
-	var diff = (window.innerWidth - totalWidth)/2;
-	document.getElementById('slider').style.height = window.innerHeight - 180 + 'px';
-	if (diff <= 0){diff = 0;}
-	document.getElementById('slider-holder').style.marginLeft = diff + 'px';
-	for (var i in audioEngineContext.audioObjects)
-	{
-		if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference'){
-			audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
-		}
-	}
-	document.getElementById('scale-holder').style.marginLeft = (diff-100) + 'px';
-	document.getElementById('scale-text-holder').style.height = window.innerHeight-194 + 'px';
+function resizeWindow(event) {
+    // Function called when the window has been resized.
+    // MANDATORY FUNCTION
+
+    var outsideRef = document.getElementById('outside-reference');
+    if (outsideRef != null) {
+        outsideRef.style.left = (window.innerWidth - 120) / 2 + 'px';
+    }
+
+    // Auto-align
+    var numObj = document.getElementsByClassName('track-slider').length;
+    var totalWidth = (numObj - 1) * 150 + 100;
+    var diff = (window.innerWidth - totalWidth) / 2;
+    document.getElementById('slider').style.height = window.innerHeight - 180 + 'px';
+    if (diff <= 0) {
+        diff = 0;
+    }
+    document.getElementById('slider-holder').style.marginLeft = diff + 'px';
+    for (var i in audioEngineContext.audioObjects) {
+        if (audioEngineContext.audioObjects[i].specification.type != 'outside-reference') {
+            audioEngineContext.audioObjects[i].interfaceDOM.resize(event);
+        }
+    }
+    document.getElementById('scale-holder').style.marginLeft = (diff - 100) + 'px';
+    document.getElementById('scale-text-holder').style.height = window.innerHeight - 194 + 'px';
     // Cheers edge for making me delete a canvas every resize.
-	var canvas = document.getElementById('scale-canvas');
+    var canvas = document.getElementById('scale-canvas');
     var new_canvas = document.createElement("canvas");
     new_canvas.id = 'scale-canvas';
     canvas.parentElement.appendChild(new_canvas);
     canvas.parentElement.removeChild(canvas);
-	new_canvas.width = totalWidth;
-	new_canvas.height = window.innerHeight-194;
-	drawScale();
+    new_canvas.width = totalWidth;
+    new_canvas.height = window.innerHeight - 194;
+    drawScale();
 }
 
-function drawScale()
-{
-	var interfaceObj = testState.currentStateMap.interfaces[0];
-	var scales = testState.currentStateMap.interfaces[0].scales;
-	scales = scales.sort(function(a,b) {
-		return a.position - b.position;
-	});
-	var canvas = document.getElementById('scale-canvas');
-	var ctx = canvas.getContext("2d");
-	var height = canvas.height;
-	var width = canvas.width;
-    ctx.clearRect(0,0,canvas.width,canvas.height);
-	var draw_heights = [24, height-34];
-	var textHolder = document.getElementById('scale-text-holder');
-	textHolder.innerHTML = "";
-	var lastHeight = 0;
-	for (var scale of scales)
-	{
-		var posPercent = scale.position / 100.0;
-		var posPix = (1-posPercent)*(draw_heights[1]-draw_heights[0])+draw_heights[0];
-		ctx.fillStyle = "#000000";
-		ctx.setLineDash([1,2]);
-		ctx.moveTo(0,posPix);
-		ctx.lineTo(width,posPix);
-		ctx.stroke();
-		var text = document.createElement('div');
-		text.align = "right";
-		var textC = document.createElement('span');
-		textC.textContent = scale.text;
-		text.appendChild(textC);
-		text.className = "scale-text";
-		textHolder.appendChild(text);
-		text.style.top = (posPix-9) + 'px';
-		text.style.left = 100 - ($(text).width()+3) + 'px';
-		lastHeight = posPix;
-	}
+function drawScale() {
+    var interfaceObj = testState.currentStateMap.interfaces[0];
+    var scales = testState.currentStateMap.interfaces[0].scales;
+    scales = scales.sort(function (a, b) {
+        return a.position - b.position;
+    });
+    var canvas = document.getElementById('scale-canvas');
+    var ctx = canvas.getContext("2d");
+    var height = canvas.height;
+    var width = canvas.width;
+    ctx.clearRect(0, 0, canvas.width, canvas.height);
+    var draw_heights = [24, height - 34];
+    var textHolder = document.getElementById('scale-text-holder');
+    textHolder.innerHTML = "";
+    var lastHeight = 0;
+    for (var scale of scales) {
+        var posPercent = scale.position / 100.0;
+        var posPix = (1 - posPercent) * (draw_heights[1] - draw_heights[0]) + draw_heights[0];
+        ctx.fillStyle = "#000000";
+        ctx.setLineDash([1, 2]);
+        ctx.moveTo(0, posPix);
+        ctx.lineTo(width, posPix);
+        ctx.stroke();
+        var text = document.createElement('div');
+        text.align = "right";
+        var textC = document.createElement('span');
+        textC.textContent = scale.text;
+        text.appendChild(textC);
+        text.className = "scale-text";
+        textHolder.appendChild(text);
+        text.style.top = (posPix - 9) + 'px';
+        text.style.left = 100 - ($(text).width() + 3) + 'px';
+        lastHeight = posPix;
+    }
 }
 
 function buttonSubmitClick() // TODO: Only when all songs have been played!
 {
-	var checks = [];
-	checks = checks.concat(testState.currentStateMap.interfaces[0].options);
-	checks = checks.concat(specification.interfaces.options);
-	var canContinue = true;
-	
-	// Check that the anchor and reference objects are correctly placed
-	if (interfaceContext.checkHiddenAnchor() == false) {return;}
-	if (interfaceContext.checkHiddenReference() == false) {return;}
-	
-	for (var i=0; i<checks.length; i++) {
-		if (checks[i].type == 'check')
-		{
-			switch(checks[i].name) {
-			case 'fragmentPlayed':
-				// Check if all fragments have been played
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case  'fragmentFullPlayback':
-				// Check all fragments have been played to their full length
-				var checkState = interfaceContext.checkAllPlayed();
-				if (checkState == false) {canContinue = false;}
-				console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
-				break;
-			case 'fragmentMoved':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllMoved();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'fragmentComments':
-				// Check all fragment sliders have been moved.
-				var checkState = interfaceContext.checkAllCommented();
-				if (checkState == false) {canContinue = false;}
-				break;
-			case 'scalerange':
-                // Check the scale has been used effectively
-                var checkState = interfaceContext.checkScaleRange(checks[i].min,checks[i].max);
-                if (checkState == false) {canContinue = false;}
-				break;
-			default:
-				console.log("WARNING - Check option "+checks[i].check+" is not supported on this interface");
-				break;
-			}
+    var checks = [];
+    checks = checks.concat(testState.currentStateMap.interfaces[0].options);
+    checks = checks.concat(specification.interfaces.options);
+    var canContinue = true;
 
-		}
-		if (!canContinue) {break;}
-	}
-	
+    // Check that the anchor and reference objects are correctly placed
+    if (interfaceContext.checkHiddenAnchor() == false) {
+        return;
+    }
+    if (interfaceContext.checkHiddenReference() == false) {
+        return;
+    }
+
+    for (var i = 0; i < checks.length; i++) {
+        if (checks[i].type == 'check') {
+            switch (checks[i].name) {
+                case 'fragmentPlayed':
+                    // Check if all fragments have been played
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentFullPlayback':
+                    // Check all fragments have been played to their full length
+                    var checkState = interfaceContext.checkAllPlayed();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    console.log('NOTE: fragmentFullPlayback not currently implemented, performing check fragmentPlayed instead');
+                    break;
+                case 'fragmentMoved':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllMoved();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'fragmentComments':
+                    // Check all fragment sliders have been moved.
+                    var checkState = interfaceContext.checkAllCommented();
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                case 'scalerange':
+                    // Check the scale has been used effectively
+                    var checkState = interfaceContext.checkScaleRange(checks[i].min, checks[i].max);
+                    if (checkState == false) {
+                        canContinue = false;
+                    }
+                    break;
+                default:
+                    console.log("WARNING - Check option " + checks[i].check + " is not supported on this interface");
+                    break;
+            }
+
+        }
+        if (!canContinue) {
+            break;
+        }
+    }
+
     if (canContinue) {
-	    if (audioEngineContext.status == 1) {
-	        var playback = document.getElementById('playback-button');
-	        playback.click();
-	    // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
-	    } else
-	    {
-	        if (audioEngineContext.timer.testStarted == false)
-	        {
-	            interfaceContext.lightbox.post("Message",'You have not started the test! Please press start to begin the test!');
-	            return;
-	        }
-	    }
-	    testState.advanceState();
-    } 
+        if (audioEngineContext.status == 1) {
+            var playback = document.getElementById('playback-button');
+            playback.click();
+            // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options
+        } else {
+            if (audioEngineContext.timer.testStarted == false) {
+                interfaceContext.lightbox.post("Message", 'You have not started the test! Please press start to begin the test!');
+                return;
+            }
+        }
+        testState.advanceState();
+    }
 }
 
-function pageXMLSave(store, pageSpecification)
-{
-	// MANDATORY
-	// Saves a specific test page
-	// You can use this space to add any extra nodes to your XML <audioHolder> saves
-	// Get the current <page> information in store (remember to appendChild your data to it)
-	// pageSpecification is the current page node configuration
-	// To create new XML nodes, use storage.document.createElement();
+function pageXMLSave(store, pageSpecification) {
+    // MANDATORY
+    // Saves a specific test page
+    // You can use this space to add any extra nodes to your XML <audioHolder> saves
+    // Get the current <page> information in store (remember to appendChild your data to it)
+    // pageSpecification is the current page node configuration
+    // To create new XML nodes, use storage.document.createElement();
 }
--- a/interfaces/timeline.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/interfaces/timeline.css	Mon Nov 14 14:17:03 2016 +0000
@@ -2,7 +2,6 @@
     display: flex;
     justify-content: center;
 }
-
 div.timeline-element-content {
     max-width: 800px;
     min-width: 200px;
@@ -10,15 +9,13 @@
     margin: 10px 0px;
     padding: 20px;
 }
-
 div.timeline-element-canvas-holder {
     display: flex;
     width: inherit;
     height: 160px;
     margin-left: 50px;
 }
-
-canvas.canvas-layer1{
+canvas.canvas-layer1 {
     position: absolute;
 }
 canvas.canvas-layer2 {
@@ -33,21 +30,17 @@
     position: absolute;
     z-index: -3;
 }
-
 canvas.timeline-element-canvas {
     border: 1px solid black;
 }
-
 canvas.canvas-disabled {
     background-color: gray;
 }
-
 div.timeline-element-comment-holder {
     display: flex;
     flex-wrap: wrap;
     justify-content: space-between;
 }
-
 div.comment-entry {
     border: 1px solid #444444;
     max-width: 600px;
@@ -59,13 +52,11 @@
     display: flex;
     flex-direction: column;
 }
-
 div.comment-entry-header {
     display: flex;
     justify-content: space-between;
 }
-
 textarea.comment-entry-text {
     resize: none;
     margin: auto;
-}
\ No newline at end of file
+}
--- a/js/WAVE.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/js/WAVE.js	Mon Nov 14 14:17:03 2016 +0000
@@ -1,131 +1,120 @@
 // Decode and perform WAVE file byte level manipulation
 
-find_subarray = function(arr,subarr) {
+find_subarray = function (arr, subarr) {
     var arr_length = arr.length;
     var subarr_length = subarr.length;
     var last_check_index = arr_length - subarr_length;
-    
+
     positionLoop:
-    for (var i=0; i <= last_check_index; i++)
-    {
-        for (var j=0; j< subarr_length; j++)
-        {
-            if (arr[i + j] !== subarr[j]) {
-                continue positionLoop;
+        for (var i = 0; i <= last_check_index; i++) {
+            for (var j = 0; j < subarr_length; j++) {
+                if (arr[i + j] !== subarr[j]) {
+                    continue positionLoop;
+                }
             }
+            return i;
         }
-        return i;
-    }
     return -1;
 };
 
 function convertToInteger(arr) {
     var value = 0;
-    for (var i=0; i<arr.length; i++)
-    {
-        value += arr[i]<<(i*8);
+    for (var i = 0; i < arr.length; i++) {
+        value += arr[i] << (i * 8);
     }
     return value;
 }
+
 function convertToString(arr) {
     var str = "";
-    for (var i=0; i<arr.length; i++)
-    {
+    for (var i = 0; i < arr.length; i++) {
         str = str.concat(String.fromCharCode(arr[i]));
     }
     return str;
 }
 
-function WAVE()
-{
+function WAVE() {
     // The WAVE file object
     this.status == 'WAVE_DECLARED'
-    
+
     this.decoded_data = null;
-    
+
     this.RIFF = String(); //ChunkID
-	this.size; //ChunkSize
-	this.FT_Header; //Format
-	this.fmt_marker; //Subchunk1ID
-	this.formatDataLength; //Subchunk1Size
-	this.type; //AudioFormat
-	this.num_channels; //NumChannels
-	this.sample_rate; //SampleRate
-	this.byte_rate; //ByteRate
-	this.block_align; //BlockAlign
-	this.bits_per_sample; //BitsPerSample
-	this.data_header; //Subchunk2ID
-	this.data_size; //Subchunk2Size
+    this.size; //ChunkSize
+    this.FT_Header; //Format
+    this.fmt_marker; //Subchunk1ID
+    this.formatDataLength; //Subchunk1Size
+    this.type; //AudioFormat
+    this.num_channels; //NumChannels
+    this.sample_rate; //SampleRate
+    this.byte_rate; //ByteRate
+    this.block_align; //BlockAlign
+    this.bits_per_sample; //BitsPerSample
+    this.data_header; //Subchunk2ID
+    this.data_size; //Subchunk2Size
     this.num_samples;
-    
-    this.open = function(IOArrayBuffer)
-    {
+
+    this.open = function (IOArrayBuffer) {
         var IOView8 = new Uint8Array(IOArrayBuffer);
-        this.RIFF = convertToString(IOView8.subarray(0,4));
-        if (this.RIFF != 'RIFF')
-        {
+        this.RIFF = convertToString(IOView8.subarray(0, 4));
+        if (this.RIFF != 'RIFF') {
             console.log('WAVE ERR - Not a RIFF file');
             return 1;
         }
-        this.size = convertToInteger(IOView8.subarray(4,8));
-        this.FT_Header = convertToString(IOView8.subarray(8,12));
-        this.fmt_marker = convertToString(IOView8.subarray(12,16));
-        this.formatDataLength = convertToInteger(IOView8.subarray(16,20));
-        this.type = convertToInteger(IOView8.subarray(20,22));
-        this.num_channels = convertToInteger(IOView8.subarray(22,24));
-        this.sample_rate = convertToInteger(IOView8.subarray(24,28));
-        this.byte_rate = convertToInteger(IOView8.subarray(28,32));
-        this.block_align = convertToInteger(IOView8.subarray(32,34));
-        this.bits_per_sample = convertToInteger(IOView8.subarray(34,36));
-        
+        this.size = convertToInteger(IOView8.subarray(4, 8));
+        this.FT_Header = convertToString(IOView8.subarray(8, 12));
+        this.fmt_marker = convertToString(IOView8.subarray(12, 16));
+        this.formatDataLength = convertToInteger(IOView8.subarray(16, 20));
+        this.type = convertToInteger(IOView8.subarray(20, 22));
+        this.num_channels = convertToInteger(IOView8.subarray(22, 24));
+        this.sample_rate = convertToInteger(IOView8.subarray(24, 28));
+        this.byte_rate = convertToInteger(IOView8.subarray(28, 32));
+        this.block_align = convertToInteger(IOView8.subarray(32, 34));
+        this.bits_per_sample = convertToInteger(IOView8.subarray(34, 36));
+
         // Find the data header first
-        var data_start = find_subarray(IOView8,[100, 97, 116, 97]);
-        
-        this.data_header = convertToString(IOView8.subarray(data_start,data_start+4));
-        this.data_size = convertToInteger(IOView8.subarray(data_start+4,data_start+8));
-        
+        var data_start = find_subarray(IOView8, [100, 97, 116, 97]);
+
+        this.data_header = convertToString(IOView8.subarray(data_start, data_start + 4));
+        this.data_size = convertToInteger(IOView8.subarray(data_start + 4, data_start + 8));
+
         this.num_samples = this.data_size / this.block_align;
-        
+
         this.decoded_data = [];
         if (this.type != 1 && this.type != 3) {
             console.log("Neither PCM nor IEEE float, cannot decode");
             return 1;
         }
-        for (var c=0; c<this.num_channels; c++)
-        {
+        for (var c = 0; c < this.num_channels; c++) {
             this.decoded_data.push(new Float32Array(this.num_samples));
         }
-        var sampleDataOffset = data_start+8;
-        
+        var sampleDataOffset = data_start + 8;
+
         // Now need to decode the data from sampleDataOffset
         // Data is always interleved
         var data_view;
-        if (this.type == 3)
-        {
+        if (this.type == 3) {
             // Already in float
             if (this.bits_per_sample == 32) {
-                data_view = new Float32Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size));
+                data_view = new Float32Array(IOArrayBuffer.slice(sampleDataOffset, sampleDataOffset + this.data_size));
             } else if (this.bits_per_sample == 64) {
-                data_view = new Float64Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size));
+                data_view = new Float64Array(IOArrayBuffer.slice(sampleDataOffset, sampleDataOffset + this.data_size));
             }
-        } else if (this.type == 1)
-        {
-            data_view = new Float32Array(this.num_samples*this.num_channels);
-            integerConvert(new Uint8Array(IOArrayBuffer.slice(sampleDataOffset,sampleDataOffset+this.data_size)),data_view,this.bits_per_sample/8);
+        } else if (this.type == 1) {
+            data_view = new Float32Array(this.num_samples * this.num_channels);
+            integerConvert(new Uint8Array(IOArrayBuffer.slice(sampleDataOffset, sampleDataOffset + this.data_size)), data_view, this.bits_per_sample / 8);
         }
-        deInterlace(data_view,this.decoded_data);
+        deInterlace(data_view, this.decoded_data);
         return 0;
     };
 }
 
-function deInterlace(src_array, dst_array)
-{
+function deInterlace(src_array, dst_array) {
     var number = src_array.length;
     var channels = dst_array.length;
     var channel_index = 0;
     var dst_index = 0;
-    for (var n=0; n<number; n++)
-    {
+    for (var n = 0; n < number; n++) {
         dst_array[channel_index][dst_index] = src_array[n];
         channel_index++;
         if (channel_index >= channels) {
@@ -135,21 +124,18 @@
     }
 }
 
-function integerConvert(srcView,dstView,srcBytes)
-{
+function integerConvert(srcView, dstView, srcBytes) {
     //Convert integers of a Uint8Array of certain byte length into a Float32Array
     var number = dstView.length;
-    var outBits = srcBytes*8;
+    var outBits = srcBytes * 8;
     var endShift = 32 - outBits;
-    if (srcView.length != dstView.length*srcBytes)
-    {
+    if (srcView.length != dstView.length * srcBytes) {
         return -1;
     }
-    for (var n=0; n<number; n++)
-    {
-        var srcIndex = n*srcBytes;
-        var intData = convertToInteger(srcView.subarray(srcIndex,srcIndex+srcBytes));
+    for (var n = 0; n < number; n++) {
+        var srcIndex = n * srcBytes;
+        var intData = convertToInteger(srcView.subarray(srcIndex, srcIndex + srcBytes));
         intData = (intData << (endShift));
         dstView[n] = intData / 2147483648;
     }
-}
\ No newline at end of file
+}
--- a/js/loader.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/js/loader.js	Mon Nov 14 14:17:03 2016 +0000
@@ -1,6 +1,6 @@
 // Script to load the relevant JS files if the system supports it
 
-window.onload = function() {
+window.onload = function () {
     // First check if the Web Audio API is supported
     if (window.AudioContext == undefined && window.webkitAudioContext == undefined) {
         // Display unsuported error message
@@ -16,7 +16,7 @@
     } else {
         var head = document.getElementsByTagName("head")[0];
         var src_list = ['js/specification.js', 'js/core.js', 'js/loudness.js', 'js/xmllint.js', 'js/WAVE.js'];
-        for (var i=0; i<src_list.length; i++) {
+        for (var i = 0; i < src_list.length; i++) {
             var src = src_list[i];
             var script = document.createElement("script");
             script.type = "text/javascript";
@@ -26,4 +26,4 @@
             head.appendChild(script);
         }
     }
-}
\ No newline at end of file
+}
--- a/js/loudness.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/js/loudness.js	Mon Nov 14 14:17:03 2016 +0000
@@ -8,98 +8,88 @@
 
 var interval_cal_loudness_event = null;
 
-if (typeof OfflineAudioContext == "undefined"){
-	var OfflineAudioContext = webkitOfflineAudioContext;
+if (typeof OfflineAudioContext == "undefined") {
+    var OfflineAudioContext = webkitOfflineAudioContext;
 }
 
-function calculateLoudness(buffer, timescale, target, offlineContext)
-{
-	// This function returns the EBU R 128 specification loudness model and sets the linear gain required to match -23 LUFS
-	// buffer -> Web Audio API Buffer object
-	// timescale -> M or Momentary (returns Array), S or Short (returns Array),
-	//   I or Integrated (default, returns number)
-	// target -> default is -23 LUFS but can be any LUFS measurement.
-	if(navigator.platform == 'iPad' || navigator.platform == 'iPhone') {
+function calculateLoudness(buffer, timescale, target, offlineContext) {
+    // This function returns the EBU R 128 specification loudness model and sets the linear gain required to match -23 LUFS
+    // buffer -> Web Audio API Buffer object
+    // timescale -> M or Momentary (returns Array), S or Short (returns Array),
+    //   I or Integrated (default, returns number)
+    // target -> default is -23 LUFS but can be any LUFS measurement.
+    if (navigator.platform == 'iPad' || navigator.platform == 'iPhone') {
         buffer.ready();
     }
-	if (buffer == undefined)
-	{
-		return 0;
-	}
-	if (timescale == undefined)
-	{
-		timescale = "I";
-	}
-	if (target == undefined)
-	{
-		target = -23;
-	}
-	if (offlineContext == undefined)
-	{
-		offlineContext = new OfflineAudioContext(audioContext.destination.channelCount, buffer.buffer.duration*audioContext.sampleRate, audioContext.sampleRate);
-	}
-	// Create the required filters
-	var KFilter = offlineContext.createBiquadFilter();
-	KFilter.type = "highshelf";
-	KFilter.gain.value = 4;
-	KFilter.frequency.value = 1500;
-	
-	var HPFilter = offlineContext.createBiquadFilter();
-	HPFilter.type = "highpass";
-	HPFilter.Q.value = 0.5;
-	HPFilter.frequency.value = 38;
-	// copy Data into the process buffer
-	var processSource = offlineContext.createBufferSource();
-	processSource.buffer = buffer.buffer;
-	
-	processSource.connect(KFilter);
-	KFilter.connect(HPFilter);
-	HPFilter.connect(offlineContext.destination);
-	offlineContext.oncomplete = function(renderedBuffer) {
-		// Have the renderedBuffer information, now continue processing
-		if (typeof renderedBuffer.renderedBuffer == 'object') {
-			renderedBuffer = renderedBuffer.renderedBuffer;
-		}
-		switch(timescale)
-		{
-		case "I":
-            // Calculate the Mean Squared of a signal
-            var MS = calculateMeanSquared(renderedBuffer,0.4,0.75);
-            // Calculate the Loudness of each block
-            var MSL = calculateLoudnessFromBlocks(MS);
-            // Get blocks from Absolute Gate
-            var LK = loudnessGate(MSL,MS,-70);
-            // Calculate Loudness
-            var LK_gate = loudnessOfBlocks(LK);
-            // Get blocks from Relative Gate
-            var RK = loudnessGate(MSL,MS,LK_gate-10);
-            var RK_gate = loudnessOfBlocks(RK);
-            buffer.buffer.lufs = RK_gate;
-		}
+    if (buffer == undefined) {
+        return 0;
+    }
+    if (timescale == undefined) {
+        timescale = "I";
+    }
+    if (target == undefined) {
+        target = -23;
+    }
+    if (offlineContext == undefined) {
+        offlineContext = new OfflineAudioContext(audioContext.destination.channelCount, buffer.buffer.duration * audioContext.sampleRate, audioContext.sampleRate);
+    }
+    // Create the required filters
+    var KFilter = offlineContext.createBiquadFilter();
+    KFilter.type = "highshelf";
+    KFilter.gain.value = 4;
+    KFilter.frequency.value = 1500;
+
+    var HPFilter = offlineContext.createBiquadFilter();
+    HPFilter.type = "highpass";
+    HPFilter.Q.value = 0.5;
+    HPFilter.frequency.value = 38;
+    // copy Data into the process buffer
+    var processSource = offlineContext.createBufferSource();
+    processSource.buffer = buffer.buffer;
+
+    processSource.connect(KFilter);
+    KFilter.connect(HPFilter);
+    HPFilter.connect(offlineContext.destination);
+    offlineContext.oncomplete = function (renderedBuffer) {
+        // Have the renderedBuffer information, now continue processing
+        if (typeof renderedBuffer.renderedBuffer == 'object') {
+            renderedBuffer = renderedBuffer.renderedBuffer;
+        }
+        switch (timescale) {
+            case "I":
+                // Calculate the Mean Squared of a signal
+                var MS = calculateMeanSquared(renderedBuffer, 0.4, 0.75);
+                // Calculate the Loudness of each block
+                var MSL = calculateLoudnessFromBlocks(MS);
+                // Get blocks from Absolute Gate
+                var LK = loudnessGate(MSL, MS, -70);
+                // Calculate Loudness
+                var LK_gate = loudnessOfBlocks(LK);
+                // Get blocks from Relative Gate
+                var RK = loudnessGate(MSL, MS, LK_gate - 10);
+                var RK_gate = loudnessOfBlocks(RK);
+                buffer.buffer.lufs = RK_gate;
+        }
         buffer.ready();
-	};
+    };
     processSource.start(0);
-	offlineContext.startRendering();
+    offlineContext.startRendering();
 }
 
-function calculateMeanSquared(buffer,frame_dur,frame_overlap)
-{
-    frame_size = Math.floor(buffer.sampleRate*frame_dur);
-    step_size = Math.floor(frame_size*(1.0-frame_overlap));
-    num_frames = Math.floor((buffer.length-frame_size)/step_size);
-    
+function calculateMeanSquared(buffer, frame_dur, frame_overlap) {
+    frame_size = Math.floor(buffer.sampleRate * frame_dur);
+    step_size = Math.floor(frame_size * (1.0 - frame_overlap));
+    num_frames = Math.floor((buffer.length - frame_size) / step_size);
+
     MS = Array(buffer.numberOfChannels);
-    for (var c=0; c<buffer.numberOfChannels; c++)
-    {
+    for (var c = 0; c < buffer.numberOfChannels; c++) {
         MS[c] = new Float32Array(num_frames);
         var data = buffer.getChannelData(c);
-        for (var no=0; no<num_frames; no++)
-        {
+        for (var no = 0; no < num_frames; no++) {
             MS[c][no] = 0.0;
-            for (var ptr=0; ptr<frame_size; ptr++)
-            {
-                var sample = data[no*step_size+ptr];
-                MS[c][no] += sample*sample;
+            for (var ptr = 0; ptr < frame_size; ptr++) {
+                var sample = data[no * step_size + ptr];
+                MS[c][no] += sample * sample;
             }
             MS[c][no] /= frame_size;
         }
@@ -107,41 +97,35 @@
     return MS;
 }
 
-function calculateLoudnessFromBlocks(blocks)
-{
+function calculateLoudnessFromBlocks(blocks) {
     var num_frames = blocks[0].length;
     var num_channels = blocks.length;
     var MSL = Array(num_frames);
-    for (var n=0; n<num_frames; n++)
-    {
+    for (var n = 0; n < num_frames; n++) {
         var sum = 0;
-        for (var c=0; c<num_channels; c++)
-        {
+        for (var c = 0; c < num_channels; c++) {
             var G = 1.0;
-            if(G >= 3){G = 1.41;}
-            sum += blocks[c][n]*G;
+            if (G >= 3) {
+                G = 1.41;
+            }
+            sum += blocks[c][n] * G;
         }
-        MSL[n] = -0.691 + 10*Math.log10(sum);
+        MSL[n] = -0.691 + 10 * Math.log10(sum);
     }
     return MSL;
 }
 
-function loudnessGate(blocks,source,threshold)
-{
+function loudnessGate(blocks, source, threshold) {
     var num_frames = source[0].length;
     var num_channels = source.length;
     var LK = Array(num_channels);
-    for (var c=0; c<num_channels; c++)
-    {
+    for (var c = 0; c < num_channels; c++) {
         LK[c] = [];
     }
-    
-    for (var n=0; n<num_frames; n++)
-    {
-        if (blocks[n] > threshold)
-        {
-            for (var c=0; c<num_channels; c++)
-            {
+
+    for (var n = 0; n < num_frames; n++) {
+        if (blocks[n] > threshold) {
+            for (var c = 0; c < num_channels; c++) {
                 LK[c].push(source[c][n]);
             }
         }
@@ -149,23 +133,22 @@
     return LK;
 }
 
-function loudnessOfBlocks(blocks)
-{
+function loudnessOfBlocks(blocks) {
     var num_frames = blocks[0].length;
     var num_channels = blocks.length;
     var loudness = 0.0;
-    for (var n=0; n<num_frames; n++)
-    {
+    for (var n = 0; n < num_frames; n++) {
         var sum = 0;
-        for (var c=0; c<num_channels; c++)
-        {
+        for (var c = 0; c < num_channels; c++) {
             var G = 1.0;
-            if(G >= 3){G = 1.41;}
-            sum += blocks[c][n]*G;
+            if (G >= 3) {
+                G = 1.41;
+            }
+            sum += blocks[c][n] * G;
         }
         sum /= num_frames;
         loudness += sum;
     }
     loudness = -0.691 + 10 * Math.log10(loudness);
     return loudness;
-}
\ No newline at end of file
+}
--- a/js/specification.js	Mon Nov 14 12:11:38 2016 +0000
+++ b/js/specification.js	Mon Nov 14 14:17:03 2016 +0000
@@ -1,12 +1,12 @@
 function Specification() {
-	// Handles the decoding of the project specification XML into a simple JavaScript Object.
-	
+    // Handles the decoding of the project specification XML into a simple JavaScript Object.
+
     // <setup> attributes
-	this.interface = null;
-	this.projectReturn = null;
+    this.interface = null;
+    this.projectReturn = null;
     this.returnURL = null;
-	this.randomiseOrder = null;
-	this.poolSize = null;
+    this.randomiseOrder = null;
+    this.poolSize = null;
     this.loudness = null;
     this.sampleRate = null;
     this.calibration = null;
@@ -14,32 +14,31 @@
     this.preSilence = null;
     this.postSilence = null;
     this.playOne = null;
-    
+
     // nodes
     this.metrics = null;
     this.preTest = undefined;
     this.postTest = undefined;
-	this.pages = [];
-	this.interfaces = null;
-	this.errors = [];
-	this.schema = null;
+    this.pages = [];
+    this.interfaces = null;
+    this.errors = [];
+    this.schema = null;
     this.exitText = "Thank you.";
-	
-	this.processAttribute = function(attribute,schema,schemaRoot)
-	{
-		// attribute is the string returned from getAttribute on the XML
-		// schema is the <xs:attribute> node
-		if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined)
-		{
-			schema = schemaRoot.getAllElementsByName(schema.getAttribute('ref'))[0];
-		}
-		var defaultOpt = schema.getAttribute('default');
-		if (attribute == null) {
-			attribute = defaultOpt;
-		}
-		var dataType = schema.getAttribute('type');
-		if (typeof dataType == "string") { dataType = dataType.substr(3);}
-		else {
+
+    this.processAttribute = function (attribute, schema, schemaRoot) {
+        // attribute is the string returned from getAttribute on the XML
+        // schema is the <xs:attribute> node
+        if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) {
+            schema = schemaRoot.getAllElementsByName(schema.getAttribute('ref'))[0];
+        }
+        var defaultOpt = schema.getAttribute('default');
+        if (attribute == null) {
+            attribute = defaultOpt;
+        }
+        var dataType = schema.getAttribute('type');
+        if (typeof dataType == "string") {
+            dataType = dataType.substr(3);
+        } else {
             var rest = schema.getAllElementsByTagName("xs:restriction").concat(schema.getAllElementsByTagName("xs:enumeration"));
             if (rest.length > 0) {
                 dataType = rest[0].getAttribute("base");
@@ -52,129 +51,122 @@
                 dataType = "string";
             }
         }
-		if (attribute == null)
-		{
-			return attribute;
-		}
-		switch(dataType)
-		{
-		case "boolean":
-			if (attribute == 'true'){attribute = true;}else{attribute=false;}
-			break;
-		case "negativeInteger":
-		case "positiveInteger":
-		case "nonNegativeInteger":
-		case "nonPositiveInteger":
-		case "integer":
-		case "decimal":
-		case "short":
-			attribute = Number(attribute);
-			break;
-		case "string":
-		default:
-			attribute = String(attribute);
-			break;
-		}
-		return attribute;
-	};
-	
-	this.decode = function(projectXML) {
-		this.errors = [];
-		// projectXML - DOM Parsed document
-		this.projectXML = projectXML.childNodes[0];
-		var setupNode = projectXML.getElementsByTagName('setup')[0];
-		var schemaSetup = this.schema.getAllElementsByName('setup')[0];
-		// First decode the attributes
-		var attributes = schemaSetup.getAllElementsByTagName('xs:attribute');
-		for (var i=0; i<attributes.length; i++)
-		{
-			var attributeName = attributes[i].getAttribute('name') || attributes[i].getAttribute('ref');
-			var projectAttr = setupNode.getAttribute(attributeName);
-			projectAttr = this.processAttribute(projectAttr,attributes[i],this.schema);
-			switch(typeof projectAttr)
-			{
-			case "number":
-			case "boolean":
-				eval('this.'+attributeName+' = '+projectAttr);
-				break;
-			case "string":
-				eval('this.'+attributeName+' = "'+projectAttr+'"');
-				break;
-			}
-			
-		}
-        
+        if (attribute == null) {
+            return attribute;
+        }
+        switch (dataType) {
+            case "boolean":
+                if (attribute == 'true') {
+                    attribute = true;
+                } else {
+                    attribute = false;
+                }
+                break;
+            case "negativeInteger":
+            case "positiveInteger":
+            case "nonNegativeInteger":
+            case "nonPositiveInteger":
+            case "integer":
+            case "decimal":
+            case "short":
+                attribute = Number(attribute);
+                break;
+            case "string":
+            default:
+                attribute = String(attribute);
+                break;
+        }
+        return attribute;
+    };
+
+    this.decode = function (projectXML) {
+        this.errors = [];
+        // projectXML - DOM Parsed document
+        this.projectXML = projectXML.childNodes[0];
+        var setupNode = projectXML.getElementsByTagName('setup')[0];
+        var schemaSetup = this.schema.getAllElementsByName('setup')[0];
+        // First decode the attributes
+        var attributes = schemaSetup.getAllElementsByTagName('xs:attribute');
+        for (var i = 0; i < attributes.length; i++) {
+            var attributeName = attributes[i].getAttribute('name') || attributes[i].getAttribute('ref');
+            var projectAttr = setupNode.getAttribute(attributeName);
+            projectAttr = this.processAttribute(projectAttr, attributes[i], this.schema);
+            switch (typeof projectAttr) {
+                case "number":
+                case "boolean":
+                    eval('this.' + attributeName + ' = ' + projectAttr);
+                    break;
+                case "string":
+                    eval('this.' + attributeName + ' = "' + projectAttr + '"');
+                    break;
+            }
+
+        }
+
         var exitTextNode = setupNode.getElementsByTagName('exitText');
         if (exitTextNode.length == 1) {
             this.exitText = exitTextNode[0].textContent;
         }
-		
-		this.metrics = new this.metricNode();
-		
-		this.metrics.decode(this,setupNode.getElementsByTagName('metric')[0]);
-		
-		// Now process the survey node options
-		var survey = setupNode.getElementsByTagName('survey');
-		for (var i=0; i<survey.length; i++){
-			var location = survey[i].getAttribute('location');
-            switch(location)
-            {
+
+        this.metrics = new this.metricNode();
+
+        this.metrics.decode(this, setupNode.getElementsByTagName('metric')[0]);
+
+        // Now process the survey node options
+        var survey = setupNode.getElementsByTagName('survey');
+        for (var i = 0; i < survey.length; i++) {
+            var location = survey[i].getAttribute('location');
+            switch (location) {
                 case 'pre':
                 case 'before':
-	            this.preTest = new this.surveyNode(this);
-	            this.preTest.decode(this,survey[i]);
+                    this.preTest = new this.surveyNode(this);
+                    this.preTest.decode(this, survey[i]);
                     break;
                 case 'post':
                 case 'after':
                     this.postTest = new this.surveyNode(this);
-                    this.postTest.decode(this,survey[i]);
+                    this.postTest.decode(this, survey[i]);
                     break;
             }
-		}
-		
-		var interfaceNode = setupNode.getElementsByTagName('interface');
-		if (interfaceNode.length > 1)
-		{
-			this.errors.push("Only one <interface> node in the <setup> node allowed! Others except first ingnored!");
-		}
-		this.interfaces = new this.interfaceNode(this);
-		if (interfaceNode.length != 0)
-		{
-			interfaceNode = interfaceNode[0];
-			this.interfaces.decode(this,interfaceNode,this.schema.getAllElementsByName('interface')[1]);
-		}
-		
-		// Page tags
-		var pageTags = projectXML.getElementsByTagName('page');
-		var pageSchema = this.schema.getAllElementsByName('page')[0];
-		for (var i=0; i<pageTags.length; i++)
-		{
-			var node = new this.page(this);
-			node.decode(this,pageTags[i],pageSchema);
-			this.pages.push(node);
-		}
-	};
-	
-	this.encode = function()
-	{
-		var RootDocument = document.implementation.createDocument(null,"waet");
-		var root = RootDocument.firstChild;
-        root.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
-        root.setAttribute("xsi:noNamespaceSchemaLocation","test-schema.xsd");
-		// Build setup node
+        }
+
+        var interfaceNode = setupNode.getElementsByTagName('interface');
+        if (interfaceNode.length > 1) {
+            this.errors.push("Only one <interface> node in the <setup> node allowed! Others except first ingnored!");
+        }
+        this.interfaces = new this.interfaceNode(this);
+        if (interfaceNode.length != 0) {
+            interfaceNode = interfaceNode[0];
+            this.interfaces.decode(this, interfaceNode, this.schema.getAllElementsByName('interface')[1]);
+        }
+
+        // Page tags
+        var pageTags = projectXML.getElementsByTagName('page');
+        var pageSchema = this.schema.getAllElementsByName('page')[0];
+        for (var i = 0; i < pageTags.length; i++) {
+            var node = new this.page(this);
+            node.decode(this, pageTags[i], pageSchema);
+            this.pages.push(node);
+        }
+    };
+
+    this.encode = function () {
+        var RootDocument = document.implementation.createDocument(null, "waet");
+        var root = RootDocument.firstChild;
+        root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+        root.setAttribute("xsi:noNamespaceSchemaLocation", "test-schema.xsd");
+        // Build setup node
         var setup = RootDocument.createElement("setup");
         var schemaSetup = this.schema.getAllElementsByName('setup')[0];
         // First decode the attributes
         var attributes = schemaSetup.getAllElementsByTagName('xs:attribute');
-        for (var i=0; i<attributes.length; i++)
-        {
+        for (var i = 0; i < attributes.length; i++) {
             var name = attributes[i].getAttribute("name");
             if (name == undefined) {
                 name = attributes[i].getAttribute("ref");
             }
-            if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required")
-            {
-                eval("setup.setAttribute('"+name+"',this."+name+")");
+            if (eval("this." + name + " != undefined") || attributes[i].getAttribute("use") == "required") {
+                eval("setup.setAttribute('" + name + "',this." + name + ")");
             }
         }
         root.appendChild(setup);
@@ -188,73 +180,71 @@
         setup.appendChild(this.postTest.encode(RootDocument));
         setup.appendChild(this.metrics.encode(RootDocument));
         setup.appendChild(this.interfaces.encode(RootDocument));
-        for (var page of this.pages)
-        {
+        for (var page of this.pages) {
             root.appendChild(page.encode(RootDocument));
         }
-		return RootDocument;
-	};
-	
-	this.surveyNode = function(specification) {
-		this.location = null;
-		this.options = [];
+        return RootDocument;
+    };
+
+    this.surveyNode = function (specification) {
+        this.location = null;
+        this.options = [];
         this.parent = null;
-		this.schema = specification.schema.getAllElementsByName('survey')[0];
+        this.schema = specification.schema.getAllElementsByName('survey')[0];
         this.specification = specification;
-		
-		this.OptionNode = function(specification) {
-			this.type = undefined;
-			this.schema = specification.schema.getAllElementsByName('surveyentry')[0];
-			this.id = undefined;
+
+        this.OptionNode = function (specification) {
+            this.type = undefined;
+            this.schema = specification.schema.getAllElementsByName('surveyentry')[0];
+            this.id = undefined;
             this.name = undefined;
-			this.mandatory = undefined;
-			this.statement = undefined;
-			this.boxsize = undefined;
-			this.options = [];
-			this.min = undefined;
-			this.max = undefined;
-			this.step = undefined;
+            this.mandatory = undefined;
+            this.statement = undefined;
+            this.boxsize = undefined;
+            this.options = [];
+            this.min = undefined;
+            this.max = undefined;
+            this.step = undefined;
             this.conditions = [];
-			
-			this.decode = function(parent,child)
-			{
-				var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
-				for (var i in attributeMap){
-					if(isNaN(Number(i)) == true){break;}
-					var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
-					var projectAttr = child.getAttribute(attributeName);
-					projectAttr = parent.processAttribute(projectAttr,attributeMap[i],parent.schema);
-					switch(typeof projectAttr)
-					{
-					case "number":
-					case "boolean":
-						eval('this.'+attributeName+' = '+projectAttr);
-						break;
-					case "string":
-						eval('this.'+attributeName+' = "'+projectAttr+'"');
-						break;
-					}
-				}
-				this.statement = child.getElementsByTagName('statement')[0].textContent;
-				if (this.type == "checkbox" || this.type == "radio") {
-					var children = child.getElementsByTagName('option');
-					if (children.length == null) {
-						console.log('Malformed' +child.nodeName+ 'entry');
-						this.statement = 'Malformed' +child.nodeName+ 'entry';
-						this.type = 'statement';
-					} else {
-						this.options = [];
-						for (var i=0; i<children.length; i++)
-						{
-							this.options.push({
-								name: children[i].getAttribute('name'),
-								text: children[i].textContent
-							});
-						}
-					}
-				}
+
+            this.decode = function (parent, child) {
+                var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
+                for (var i in attributeMap) {
+                    if (isNaN(Number(i)) == true) {
+                        break;
+                    }
+                    var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
+                    var projectAttr = child.getAttribute(attributeName);
+                    projectAttr = parent.processAttribute(projectAttr, attributeMap[i], parent.schema);
+                    switch (typeof projectAttr) {
+                        case "number":
+                        case "boolean":
+                            eval('this.' + attributeName + ' = ' + projectAttr);
+                            break;
+                        case "string":
+                            eval('this.' + attributeName + ' = "' + projectAttr + '"');
+                            break;
+                    }
+                }
+                this.statement = child.getElementsByTagName('statement')[0].textContent;
+                if (this.type == "checkbox" || this.type == "radio") {
+                    var children = child.getElementsByTagName('option');
+                    if (children.length == null) {
+                        console.log('Malformed' + child.nodeName + 'entry');
+                        this.statement = 'Malformed' + child.nodeName + 'entry';
+                        this.type = 'statement';
+                    } else {
+                        this.options = [];
+                        for (var i = 0; i < children.length; i++) {
+                            this.options.push({
+                                name: children[i].getAttribute('name'),
+                                text: children[i].textContent
+                            });
+                        }
+                    }
+                }
                 var conditionElements = child.getElementsByTagName("conditional");
-                for (var i=0; i<conditionElements.length; i++) {
+                for (var i = 0; i < conditionElements.length; i++) {
                     var condition = conditionElements[i];
                     var obj = {
                         check: condition.getAttribute("check"),
@@ -264,185 +254,193 @@
                     }
                     this.conditions.push(obj);
                 }
-			};
-			
-			this.exportXML = function(doc)
-			{
-				var node = doc.createElement('surveyentry');
-				node.setAttribute('type',this.type);
-				var statement = doc.createElement('statement');
-				statement.textContent = this.statement;
-				node.appendChild(statement);
+            };
+
+            this.exportXML = function (doc) {
+                var node = doc.createElement('surveyentry');
+                node.setAttribute('type', this.type);
+                var statement = doc.createElement('statement');
+                statement.textContent = this.statement;
+                node.appendChild(statement);
                 node.id = this.id;
-                if (this.name != undefined) { node.setAttribute("name",this.name);}
-                if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
+                if (this.name != undefined) {
+                    node.setAttribute("name", this.name);
+                }
+                if (this.mandatory != undefined) {
+                    node.setAttribute("mandatory", this.mandatory);
+                }
                 node.id = this.id;
-                if (this.name != undefined) {node.setAttribute("name",this.name);}
-                switch(this.type)
-                {
+                if (this.name != undefined) {
+                    node.setAttribute("name", this.name);
+                }
+                switch (this.type) {
                     case "checkbox":
                     case "radio":
-                        for (var i=0; i<this.options.length; i++)
-                        {
+                        for (var i = 0; i < this.options.length; i++) {
                             var option = this.options[i];
                             var optionNode = doc.createElement("option");
-                            optionNode.setAttribute("name",option.name);
+                            optionNode.setAttribute("name", option.name);
                             optionNode.textContent = option.text;
                             node.appendChild(optionNode);
                         }
                     case "number":
-                        if (this.min != undefined) {node.setAttribute("min", this.min);}
-                        if (this.max != undefined) {node.setAttribute("max", this.max);}
+                        if (this.min != undefined) {
+                            node.setAttribute("min", this.min);
+                        }
+                        if (this.max != undefined) {
+                            node.setAttribute("max", this.max);
+                        }
                     case "question":
-                        if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);}
-                        if (this.mandatory != undefined) {node.setAttribute("mandatory",this.mandatory);}
+                        if (this.boxsize != undefined) {
+                            node.setAttribute("boxsize", this.boxsize);
+                        }
+                        if (this.mandatory != undefined) {
+                            node.setAttribute("mandatory", this.mandatory);
+                        }
                     default:
                         break;
                 }
                 for (var condition of this.conditions) {
                     var conditionDOM = doc.createElement("conditional");
-                    conditionDOM.setAttribute("check",condition.check);
-                    conditionDOM.setAttribute("value",condition.value);
-                    conditionDOM.setAttribute("jumpToOnPass",condition.jumpToOnPass);
-                    conditionDOM.setAttribute("jumpToOnFail",condition.jumpToOnFail);
+                    conditionDOM.setAttribute("check", condition.check);
+                    conditionDOM.setAttribute("value", condition.value);
+                    conditionDOM.setAttribute("jumpToOnPass", condition.jumpToOnPass);
+                    conditionDOM.setAttribute("jumpToOnFail", condition.jumpToOnFail);
                     node.appendChild(conditionDOM);
                 }
-				return node;
-			};
-		};
-		this.decode = function(parent,xml) {
+                return node;
+            };
+        };
+        this.decode = function (parent, xml) {
             this.parent = parent;
-			this.location = xml.getAttribute('location');
-			if (this.location == 'before'){this.location = 'pre';}
-			else if (this.location == 'after'){this.location = 'post';}
+            this.location = xml.getAttribute('location');
+            if (this.location == 'before') {
+                this.location = 'pre';
+            } else if (this.location == 'after') {
+                this.location = 'post';
+            }
             var children = xml.getAllElementsByTagName('surveyentry');
-			for (var i=0; i<children.length; i++)
-			{
-				var node = new this.OptionNode(this.specification);
-				node.decode(parent,children[i]);
-				this.options.push(node);
-			}
+            for (var i = 0; i < children.length; i++) {
+                var node = new this.OptionNode(this.specification);
+                node.decode(parent, children[i]);
+                this.options.push(node);
+            }
             if (this.options.length == 0) {
                 console.log("Empty survey node");
                 console.log(this);
             }
-		};
-		this.encode = function(doc) {
-			var node = doc.createElement('survey');
-			node.setAttribute('location',this.location);
-			for (var i=0; i<this.options.length; i++)
-			{
-				node.appendChild(this.options[i].exportXML(doc));
-			}
-			return node;
-		};
-	};
-	
-	this.interfaceNode = function(specification)
-	{
-		this.title = null;
-		this.name = null;
-		this.options = [];
-		this.scales = [];
-		this.schema = specification.schema.getAllElementsByName('interface')[1];
-		
-		this.decode = function(parent,xml) {
-			this.name = xml.getAttribute('name');
-			var titleNode = xml.getElementsByTagName('title');
-			if (titleNode.length == 1)
-			{
-				this.title = titleNode[0].textContent;
-			}
-			var interfaceOptionNodes = xml.getElementsByTagName('interfaceoption');
-			// Extract interfaceoption node schema
-			var interfaceOptionNodeSchema = this.schema.getAllElementsByName('interfaceoption')[0];
-			var attributeMap = interfaceOptionNodeSchema.getAllElementsByTagName('xs:attribute');
-			for (var i=0; i<interfaceOptionNodes.length; i++)
-			{
-				var ioNode = interfaceOptionNodes[i];
-				var option = {};
-				for (var j=0; j<attributeMap.length; j++)
-				{
-					var attributeName = attributeMap[j].getAttribute('name') || attributeMap[j].getAttribute('ref');
-					var projectAttr = ioNode.getAttribute(attributeName);
-                    if(parent.processAttribute) {
+        };
+        this.encode = function (doc) {
+            var node = doc.createElement('survey');
+            node.setAttribute('location', this.location);
+            for (var i = 0; i < this.options.length; i++) {
+                node.appendChild(this.options[i].exportXML(doc));
+            }
+            return node;
+        };
+    };
+
+    this.interfaceNode = function (specification) {
+        this.title = null;
+        this.name = null;
+        this.options = [];
+        this.scales = [];
+        this.schema = specification.schema.getAllElementsByName('interface')[1];
+
+        this.decode = function (parent, xml) {
+            this.name = xml.getAttribute('name');
+            var titleNode = xml.getElementsByTagName('title');
+            if (titleNode.length == 1) {
+                this.title = titleNode[0].textContent;
+            }
+            var interfaceOptionNodes = xml.getElementsByTagName('interfaceoption');
+            // Extract interfaceoption node schema
+            var interfaceOptionNodeSchema = this.schema.getAllElementsByName('interfaceoption')[0];
+            var attributeMap = interfaceOptionNodeSchema.getAllElementsByTagName('xs:attribute');
+            for (var i = 0; i < interfaceOptionNodes.length; i++) {
+                var ioNode = interfaceOptionNodes[i];
+                var option = {};
+                for (var j = 0; j < attributeMap.length; j++) {
+                    var attributeName = attributeMap[j].getAttribute('name') || attributeMap[j].getAttribute('ref');
+                    var projectAttr = ioNode.getAttribute(attributeName);
+                    if (parent.processAttribute) {
                         parent.processAttribute(projectAttr, attributeMap[j], parent.schema)
                     } else {
                         parent.parent.processAttribute(projectAttr, attributeMap[j], parent.parent.schema)
                     }
-					switch(typeof projectAttr)
-					{
-					case "number":
-					case "boolean":
-						eval('option.'+attributeName+' = '+projectAttr);
-						break;
-					case "string":
-						eval('option.'+attributeName+' = "'+projectAttr+'"');
-						break;
-					}
-				}
-				this.options.push(option);
-			}
-			
-			// Now the scales nodes
-			var scaleParent = xml.getElementsByTagName('scales');
-			if (scaleParent.length == 1) {
-				scaleParent = scaleParent[0];
+                    switch (typeof projectAttr) {
+                        case "number":
+                        case "boolean":
+                            eval('option.' + attributeName + ' = ' + projectAttr);
+                            break;
+                        case "string":
+                            eval('option.' + attributeName + ' = "' + projectAttr + '"');
+                            break;
+                    }
+                }
+                this.options.push(option);
+            }
+
+            // Now the scales nodes
+            var scaleParent = xml.getElementsByTagName('scales');
+            if (scaleParent.length == 1) {
+                scaleParent = scaleParent[0];
                 var scalelabels = scaleParent.getAllElementsByTagName('scalelabel');
-				for (var i=0; i<scalelabels.length; i++) {
-					this.scales.push({
-						text: scalelabels[i].textContent,
-						position: Number(scalelabels[i].getAttribute('position'))
-					});
-				}
-			}
-		};
-		
-		this.encode = function(doc) {
-			var node = doc.createElement("interface");
+                for (var i = 0; i < scalelabels.length; i++) {
+                    this.scales.push({
+                        text: scalelabels[i].textContent,
+                        position: Number(scalelabels[i].getAttribute('position'))
+                    });
+                }
+            }
+        };
+
+        this.encode = function (doc) {
+            var node = doc.createElement("interface");
             if (typeof name == "string")
-                node.setAttribute("name",this.name);
+                node.setAttribute("name", this.name);
             if (typeof this.title == "string") {
                 var titleNode = doc.createElement("title");
                 titleNode.textContent = this.title;
                 node.appendChild(titleNode);
             }
-            for (var option of this.options)
-            {
+            for (var option of this.options) {
                 var child = doc.createElement("interfaceoption");
-                child.setAttribute("type",option.type);
-                child.setAttribute("name",option.name);
+                child.setAttribute("type", option.type);
+                child.setAttribute("name", option.name);
                 node.appendChild(child);
             }
             if (this.scales.length != 0) {
                 var scales = doc.createElement("scales");
-                for (var scale of this.scales)
-                {
+                for (var scale of this.scales) {
                     var child = doc.createElement("scalelabel");
-                    child.setAttribute("position",scale.position);
+                    child.setAttribute("position", scale.position);
                     child.textContent = scale.text;
                     scales.appendChild(child);
                 }
                 node.appendChild(scales);
             }
             return node;
-		};
-	};
-	
-    this.metricNode = function() {
+        };
+    };
+
+    this.metricNode = function () {
         this.enabled = [];
-        this.decode = function(parent, xml) {
+        this.decode = function (parent, xml) {
             var children = xml.getElementsByTagName('metricenable');
-            for (var i in children) { 
-                if (isNaN(Number(i)) == true){break;}
+            for (var i in children) {
+                if (isNaN(Number(i)) == true) {
+                    break;
+                }
                 this.enabled.push(children[i].textContent);
             }
         }
-        this.encode = function(doc) {
+        this.encode = function (doc) {
             var node = doc.createElement('metric');
-            for (var i in this.enabled)
-            {
-                if (isNaN(Number(i)) == true){break;}
+            for (var i in this.enabled) {
+                if (isNaN(Number(i)) == true) {
+                    break;
+                }
                 var child = doc.createElement('metricenable');
                 child.textContent = this.enabled[i];
                 node.appendChild(child);
@@ -450,248 +448,232 @@
             return node;
         }
     }
-    
-	this.page = function(specification) {
-		this.presentedId = undefined;
-		this.id = undefined;
+
+    this.page = function (specification) {
+        this.presentedId = undefined;
+        this.id = undefined;
         this.title = undefined;
-		this.hostURL = undefined;
-		this.randomiseOrder = undefined;
-		this.loop = undefined;
-		this.outsideReference = null;
-		this.loudness = null;
+        this.hostURL = undefined;
+        this.randomiseOrder = undefined;
+        this.loop = undefined;
+        this.outsideReference = null;
+        this.loudness = null;
         this.label = null;
-		this.preTest = null;
-		this.postTest = null;
-		this.interfaces = [];
+        this.preTest = null;
+        this.postTest = null;
+        this.interfaces = [];
         this.playOne = null;
-		this.commentBoxPrefix = "Comment on track";
-		this.audioElements = [];
-		this.commentQuestions = [];
-		this.schema = specification.schema.getAllElementsByName("page")[0];
+        this.commentBoxPrefix = "Comment on track";
+        this.audioElements = [];
+        this.commentQuestions = [];
+        this.schema = specification.schema.getAllElementsByName("page")[0];
         this.specification = specification;
         this.parent = null;
-		
-		this.decode = function(parent,xml)
-		{
+
+        this.decode = function (parent, xml) {
             this.parent = parent;
-			var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
-			for (var i=0; i<attributeMap.length; i++)
-			{
-				var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
-				var projectAttr = xml.getAttribute(attributeName);
-				projectAttr = parent.processAttribute(projectAttr,attributeMap[i],parent.schema);
-				switch(typeof projectAttr)
-				{
-				case "number":
-				case "boolean":
-					eval('this.'+attributeName+' = '+projectAttr);
-					break;
-				case "string":
-					eval('this.'+attributeName+' = "'+projectAttr+'"');
-					break;
-				}
-			}
-            
+            var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
+            for (var i = 0; i < attributeMap.length; i++) {
+                var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
+                var projectAttr = xml.getAttribute(attributeName);
+                projectAttr = parent.processAttribute(projectAttr, attributeMap[i], parent.schema);
+                switch (typeof projectAttr) {
+                    case "number":
+                    case "boolean":
+                        eval('this.' + attributeName + ' = ' + projectAttr);
+                        break;
+                    case "string":
+                        eval('this.' + attributeName + ' = "' + projectAttr + '"');
+                        break;
+                }
+            }
+
             // Get the title
             var title = xml.getElementsByTagName('title');
             if (title.length != 0 && title[0].parentElement == xml) {
                 this.title = title[0].textContent;
             }
-			
-			// Get the Comment Box Prefix
-			var CBP = xml.getElementsByTagName('commentboxprefix');
-			if (CBP.length != 0 && CBP[0].parentElement == xml) {
-				this.commentBoxPrefix = CBP[0].textContent;
-			}
-			
-			// Now decode the interfaces
-			var interfaceNode = xml.getElementsByTagName('interface');
-			for (var i=0; i<interfaceNode.length; i++)
-			{
-				var node = new parent.interfaceNode(this.specification);
-				node.decode(this,interfaceNode[i],parent.schema.getAllElementsByName('interface')[1]);
-				this.interfaces.push(node);
-			}
-			
-			// Now process the survey node options
-			var survey = xml.getElementsByTagName('survey');
-			var surveySchema = parent.schema.getAllElementsByName('survey')[0];
-			for (var i=0; i<survey.length; i++){
-				var location = survey[i].getAttribute('location');
-				if (location == 'pre' || location == 'before')
-				{
-					if (this.preTest != null){this.errors.push("Already a pre/before test survey defined! Ignoring second!!");}
-					else {
-						this.preTest = new parent.surveyNode(this.specification);
-						this.preTest.decode(parent,survey[i],surveySchema);
-					}
-				} else if (location == 'post' || location == 'after') {
-					if (this.postTest != null){this.errors.push("Already a post/after test survey defined! Ignoring second!!");}
-					else {
-						this.postTest = new parent.surveyNode(this.specification);
-						this.postTest.decode(parent,survey[i],surveySchema);
-					}
-				}
-			}
-			
-			// Now process the audioelement tags
-			var audioElements = xml.getElementsByTagName('audioelement');
-			for (var i=0; i<audioElements.length; i++)
-			{
-				var node = new this.audioElementNode(this.specification);
-				node.decode(this,audioElements[i]);
-				this.audioElements.push(node);
-			}
-			
-			// Now decode the commentquestions
-			var commentQuestions = xml.getElementsByTagName('commentquestion');
-			for (var i=0; i<commentQuestions.length; i++)
-			{
-				var node = new this.commentQuestionNode(this.specification);
-				node.decode(parent,commentQuestions[i]);
-				this.commentQuestions.push(node);
-			}
-		};
-		
-		this.encode = function(root)
-		{
-			var AHNode = root.createElement("page");
+
+            // Get the Comment Box Prefix
+            var CBP = xml.getElementsByTagName('commentboxprefix');
+            if (CBP.length != 0 && CBP[0].parentElement == xml) {
+                this.commentBoxPrefix = CBP[0].textContent;
+            }
+
+            // Now decode the interfaces
+            var interfaceNode = xml.getElementsByTagName('interface');
+            for (var i = 0; i < interfaceNode.length; i++) {
+                var node = new parent.interfaceNode(this.specification);
+                node.decode(this, interfaceNode[i], parent.schema.getAllElementsByName('interface')[1]);
+                this.interfaces.push(node);
+            }
+
+            // Now process the survey node options
+            var survey = xml.getElementsByTagName('survey');
+            var surveySchema = parent.schema.getAllElementsByName('survey')[0];
+            for (var i = 0; i < survey.length; i++) {
+                var location = survey[i].getAttribute('location');
+                if (location == 'pre' || location == 'before') {
+                    if (this.preTest != null) {
+                        this.errors.push("Already a pre/before test survey defined! Ignoring second!!");
+                    } else {
+                        this.preTest = new parent.surveyNode(this.specification);
+                        this.preTest.decode(parent, survey[i], surveySchema);
+                    }
+                } else if (location == 'post' || location == 'after') {
+                    if (this.postTest != null) {
+                        this.errors.push("Already a post/after test survey defined! Ignoring second!!");
+                    } else {
+                        this.postTest = new parent.surveyNode(this.specification);
+                        this.postTest.decode(parent, survey[i], surveySchema);
+                    }
+                }
+            }
+
+            // Now process the audioelement tags
+            var audioElements = xml.getElementsByTagName('audioelement');
+            for (var i = 0; i < audioElements.length; i++) {
+                var node = new this.audioElementNode(this.specification);
+                node.decode(this, audioElements[i]);
+                this.audioElements.push(node);
+            }
+
+            // Now decode the commentquestions
+            var commentQuestions = xml.getElementsByTagName('commentquestion');
+            for (var i = 0; i < commentQuestions.length; i++) {
+                var node = new this.commentQuestionNode(this.specification);
+                node.decode(parent, commentQuestions[i]);
+                this.commentQuestions.push(node);
+            }
+        };
+
+        this.encode = function (root) {
+            var AHNode = root.createElement("page");
             // First decode the attributes
             var attributes = this.schema.getAllElementsByTagName('xs:attribute');
-            for (var i=0; i<attributes.length; i++)
-            {
+            for (var i = 0; i < attributes.length; i++) {
                 var name = attributes[i].getAttribute("name");
                 if (name == undefined) {
                     name = attributes[i].getAttribute("ref");
                 }
-                if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required")
-                {
-                    eval("AHNode.setAttribute('"+name+"',this."+name+")");
+                if (eval("this." + name + " != undefined") || attributes[i].getAttribute("use") == "required") {
+                    eval("AHNode.setAttribute('" + name + "',this." + name + ")");
                 }
             }
-			if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);}
+            if (this.loudness != null) {
+                AHNode.setAttribute("loudness", this.loudness);
+            }
             // <commentboxprefix>
             var commentboxprefix = root.createElement("commentboxprefix");
             commentboxprefix.textContent = this.commentBoxPrefix;
             AHNode.appendChild(commentboxprefix);
-            
-			for (var i=0; i<this.interfaces.length; i++)
-			{
-				AHNode.appendChild(this.interfaces[i].encode(root));
-			}
-			
-			for (var i=0; i<this.audioElements.length; i++) {
-				AHNode.appendChild(this.audioElements[i].encode(root));
-			}
-			// Create <CommentQuestion>
-			for (var i=0; i<this.commentQuestions.length; i++)
-			{
-				AHNode.appendChild(this.commentQuestions[i].encode(root));
-			}
-			
-			AHNode.appendChild(this.preTest.encode(root));
+
+            for (var i = 0; i < this.interfaces.length; i++) {
+                AHNode.appendChild(this.interfaces[i].encode(root));
+            }
+
+            for (var i = 0; i < this.audioElements.length; i++) {
+                AHNode.appendChild(this.audioElements[i].encode(root));
+            }
+            // Create <CommentQuestion>
+            for (var i = 0; i < this.commentQuestions.length; i++) {
+                AHNode.appendChild(this.commentQuestions[i].encode(root));
+            }
+
+            AHNode.appendChild(this.preTest.encode(root));
             AHNode.appendChild(this.postTest.encode(root));
-			return AHNode;
-		};
-		
-		this.commentQuestionNode = function(specification) {
-			this.id = null;
+            return AHNode;
+        };
+
+        this.commentQuestionNode = function (specification) {
+            this.id = null;
             this.name = undefined;
-			this.type = undefined;
-			this.options = [];
-			this.statement = undefined;
-			this.schema = specification.schema.getAllElementsByName('commentquestion')[0];
-			this.decode = function(parent,xml)
-			{
-				this.id = xml.id;
+            this.type = undefined;
+            this.options = [];
+            this.statement = undefined;
+            this.schema = specification.schema.getAllElementsByName('commentquestion')[0];
+            this.decode = function (parent, xml) {
+                this.id = xml.id;
                 this.name = xml.getAttribute('name');
-				this.type = xml.getAttribute('type');
-				this.statement = xml.getElementsByTagName('statement')[0].textContent;
-				var optNodes = xml.getElementsByTagName('option');
-				for (var i=0; i<optNodes.length; i++)
-				{
-					var optNode = optNodes[i];
-					this.options.push({
-						name: optNode.getAttribute('name'),
-						text: optNode.textContent
-					});
-				}
-			};
-			
-			this.encode = function(root)
-			{
-				var node = root.createElement("commentquestion");
+                this.type = xml.getAttribute('type');
+                this.statement = xml.getElementsByTagName('statement')[0].textContent;
+                var optNodes = xml.getElementsByTagName('option');
+                for (var i = 0; i < optNodes.length; i++) {
+                    var optNode = optNodes[i];
+                    this.options.push({
+                        name: optNode.getAttribute('name'),
+                        text: optNode.textContent
+                    });
+                }
+            };
+
+            this.encode = function (root) {
+                var node = root.createElement("commentquestion");
                 node.id = this.id;
-                node.setAttribute("type",this.type);
-                if (this.name != undefined){node.setAttribute("name",this.name);}
+                node.setAttribute("type", this.type);
+                if (this.name != undefined) {
+                    node.setAttribute("name", this.name);
+                }
                 var statement = root.createElement("statement");
                 statement.textContent = this.statement;
                 node.appendChild(statement);
-                for (var option of this.options)
-                {
+                for (var option of this.options) {
                     var child = root.createElement("option");
-                    child.setAttribute("name",option.name);
+                    child.setAttribute("name", option.name);
                     child.textContent = option.text;
                     node.appendChild(child);
                 }
                 return node;
-			};
-		};
-		
-		this.audioElementNode = function(specification) {
-			this.url = null;
-			this.id = null;
+            };
+        };
+
+        this.audioElementNode = function (specification) {
+            this.url = null;
+            this.id = null;
             this.name = null;
-			this.parent = null;
-			this.type = null;
-			this.marker = null;
-			this.enforce = false;
-			this.gain = 0.0;
+            this.parent = null;
+            this.type = null;
+            this.marker = null;
+            this.enforce = false;
+            this.gain = 0.0;
             this.label = null;
             this.startTime = undefined;
             this.stopTime = undefined;
-			this.schema = specification.schema.getAllElementsByName('audioelement')[0];;
-			this.parent = null;
-			this.decode = function(parent,xml)
-			{
-				this.parent = parent;
-				var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
-				for (var i=0; i<attributeMap.length; i++)
-				{
-					var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
-					var projectAttr = xml.getAttribute(attributeName);
-					projectAttr = parent.parent.processAttribute(projectAttr,attributeMap[i],parent.parent.schema);
-					switch(typeof projectAttr)
-					{
-					case "number":
-					case "boolean":
-						eval('this.'+attributeName+' = '+projectAttr);
-						break;
-					case "string":
-						eval('this.'+attributeName+' = "'+projectAttr+'"');
-						break;
-					}
-				}
-				
-			};
-			this.encode = function(root)
-			{
-				var AENode = root.createElement("audioelement");
-				var attributes = this.schema.getAllElementsByTagName('xs:attribute');
-                for (var i=0; i<attributes.length; i++)
-                {
+            this.schema = specification.schema.getAllElementsByName('audioelement')[0];;
+            this.parent = null;
+            this.decode = function (parent, xml) {
+                this.parent = parent;
+                var attributeMap = this.schema.getAllElementsByTagName('xs:attribute');
+                for (var i = 0; i < attributeMap.length; i++) {
+                    var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref');
+                    var projectAttr = xml.getAttribute(attributeName);
+                    projectAttr = parent.parent.processAttribute(projectAttr, attributeMap[i], parent.parent.schema);
+                    switch (typeof projectAttr) {
+                        case "number":
+                        case "boolean":
+                            eval('this.' + attributeName + ' = ' + projectAttr);
+                            break;
+                        case "string":
+                            eval('this.' + attributeName + ' = "' + projectAttr + '"');
+                            break;
+                    }
+                }
+
+            };
+            this.encode = function (root) {
+                var AENode = root.createElement("audioelement");
+                var attributes = this.schema.getAllElementsByTagName('xs:attribute');
+                for (var i = 0; i < attributes.length; i++) {
                     var name = attributes[i].getAttribute("name");
                     if (name == undefined) {
                         name = attributes[i].getAttribute("ref");
                     }
-                    if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required")
-                    {
-                        eval("AENode.setAttribute('"+name+"',this."+name+")");
+                    if (eval("this." + name + " != undefined") || attributes[i].getAttribute("use") == "required") {
+                        eval("AENode.setAttribute('" + name + "',this." + name + ")");
                     }
                 }
-				return AENode;
-			};
-		};
-	};
+                return AENode;
+            };
+        };
+    };
 }
--- a/php/comment_parser.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/comment_parser.php	Mon Nov 14 14:17:03 2016 +0000
@@ -148,4 +148,4 @@
 } else {
     echo "FATAL - No saved XML files discovered";
 }
-?>
\ No newline at end of file
+?>
--- a/php/get_filtered_count.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/get_filtered_count.php	Mon Nov 14 14:17:03 2016 +0000
@@ -107,4 +107,4 @@
     echo '{"urls": ["'.implode('","',$files).'"]}';
 }
 
-?>
\ No newline at end of file
+?>
--- a/php/get_filtered_score.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/get_filtered_score.php	Mon Nov 14 14:17:03 2016 +0000
@@ -196,4 +196,4 @@
         }
         echo $doc_string;
 }
-?>
\ No newline at end of file
+?>
--- a/php/get_tests.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/get_tests.php	Mon Nov 14 14:17:03 2016 +0000
@@ -68,4 +68,4 @@
         echo '{"error": "format can only be JSON"}';
 }
 
-?>
\ No newline at end of file
+?>
--- a/php/pool.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/pool.php	Mon Nov 14 14:17:03 2016 +0000
@@ -109,4 +109,4 @@
 
 echo $new_doc->saveXML();
 
-?>
\ No newline at end of file
+?>
--- a/php/rel2abs.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/rel2abs.php	Mon Nov 14 14:17:03 2016 +0000
@@ -29,4 +29,4 @@
     /* absolute URL is ready! */
     return $scheme.'://'.$abs;
 }
-?>
\ No newline at end of file
+?>
--- a/php/save.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/save.php	Mon Nov 14 14:17:03 2016 +0000
@@ -35,4 +35,4 @@
 	// Return XML confirmation data
 	$xml = '<response state="OK"><message>OK</message><file bytes="'.$wbytes.'">"'.$filename.'"</file></response>';
 	echo $xml;
-?>
\ No newline at end of file
+?>
--- a/php/score_parser.php	Mon Nov 14 12:11:38 2016 +0000
+++ b/php/score_parser.php	Mon Nov 14 14:17:03 2016 +0000
@@ -195,4 +195,4 @@
     echo "FATAL - No saved XML files discovered";
 }
 
-?>
\ No newline at end of file
+?>
--- a/python/comment_parser.html	Mon Nov 14 12:11:38 2016 +0000
+++ b/python/comment_parser.html	Mon Nov 14 14:17:03 2016 +0000
@@ -1,72 +1,78 @@
 <html lang="en">
-    <head>
-        <meta charset="utf-8" />
-        <script type="text/javascript">
-            function getXML()
-            {
-                var XMLHttp = new XMLHttpRequest();
-                XMLHttp.open("GET","comment_parser.php?format=XML",true);
-                XMLHttp.onload = function() {
-                    // Now we have the XML data, extract
-                    var parse = new DOMParser();
-                    var ajax = parse.parseFromString(XMLHttp.response,'text/xml');
-                    
-                    var parent = document.createElement("div");
-                    parent.appendChild(ajax.children[0]);
-                    var file = [parent.innerHTML];
-                    var bb = new Blob(file,{type : 'application/xml'});
-                    generateLink(bb,".xml");
-                }
-                XMLHttp.send();
+
+<head>
+    <meta charset="utf-8" />
+    <script type="text/javascript">
+        function getXML() {
+            var XMLHttp = new XMLHttpRequest();
+            XMLHttp.open("GET", "comment_parser.php?format=XML", true);
+            XMLHttp.onload = function() {
+                // Now we have the XML data, extract
+                var parse = new DOMParser();
+                var ajax = parse.parseFromString(XMLHttp.response, 'text/xml');
+
+                var parent = document.createElement("div");
+                parent.appendChild(ajax.children[0]);
+                var file = [parent.innerHTML];
+                var bb = new Blob(file, {
+                    type: 'application/xml'
+                });
+                generateLink(bb, ".xml");
             }
-            
-            function getJSON()
-            {
-                var XMLHttp = new XMLHttpRequest();
-                XMLHttp.open("GET","comment_parser.php?format=JSON",true);
-                XMLHttp.onload = function() {
-                    // Now we have the XML data, extract
-                    var file = [XMLHttp.response];
-                    var bb = new Blob(file,{type : 'application/json'});
-                    generateLink(bb,".json");
-                }
-                XMLHttp.send();
+            XMLHttp.send();
+        }
+
+        function getJSON() {
+            var XMLHttp = new XMLHttpRequest();
+            XMLHttp.open("GET", "comment_parser.php?format=JSON", true);
+            XMLHttp.onload = function() {
+                // Now we have the XML data, extract
+                var file = [XMLHttp.response];
+                var bb = new Blob(file, {
+                    type: 'application/json'
+                });
+                generateLink(bb, ".json");
             }
-            
-            function getCSV()
-            {
-                var XMLHttp = new XMLHttpRequest();
-                XMLHttp.open("GET","comment_parser.php?format=CSV",true);
-                XMLHttp.onload = function() {
-                    // Now we have the XML data, extract
-                    var file = [XMLHttp.response];
-                    var bb = new Blob(file,{type : 'text/csv'});
-                    generateLink(bb,".csv");
-                }
-                XMLHttp.send();
+            XMLHttp.send();
+        }
+
+        function getCSV() {
+            var XMLHttp = new XMLHttpRequest();
+            XMLHttp.open("GET", "comment_parser.php?format=CSV", true);
+            XMLHttp.onload = function() {
+                // Now we have the XML data, extract
+                var file = [XMLHttp.response];
+                var bb = new Blob(file, {
+                    type: 'text/csv'
+                });
+                generateLink(bb, ".csv");
             }
-            
-            function generateLink(blobfile,fmt)
-            {
-                var dnlk = window.URL.createObjectURL(blobfile);
-                var a = document.createElement("a");
-                a.hidden = '';
-                a.href = dnlk;
-                a.download = "save"+fmt;
-                a.textContent = "Save File";
-                document.getElementById("download").appendChild(a);
-            }
-        </script>
-    </head>
-    <body>
-        <h1>WAET Test Results Analysis</h1>
-        <h2>Comment Extraction</h2>
-        <p>All of the XMLs in the server 'saves/' directory are automatically parsed and downloaded, extracting only the comments. Simply select the comments you wish to extract below and your desired data format.</p>
-        <div id="download"></div>
-        <div>
-            <button onclick="getXML();">XML</button>
-            <button onclick="getJSON();">JSON</button>
-            <button onclick="getCSV();">CSV</button>
-        </div>
-    </body>
-</html>
\ No newline at end of file
+            XMLHttp.send();
+        }
+
+        function generateLink(blobfile, fmt) {
+            var dnlk = window.URL.createObjectURL(blobfile);
+            var a = document.createElement("a");
+            a.hidden = '';
+            a.href = dnlk;
+            a.download = "save" + fmt;
+            a.textContent = "Save File";
+            document.getElementById("download").appendChild(a);
+        }
+
+    </script>
+</head>
+
+<body>
+    <h1>WAET Test Results Analysis</h1>
+    <h2>Comment Extraction</h2>
+    <p>All of the XMLs in the server 'saves/' directory are automatically parsed and downloaded, extracting only the comments. Simply select the comments you wish to extract below and your desired data format.</p>
+    <div id="download"></div>
+    <div>
+        <button onclick="getXML();">XML</button>
+        <button onclick="getJSON();">JSON</button>
+        <button onclick="getCSV();">CSV</button>
+    </div>
+</body>
+
+</html>
--- a/test.html	Mon Nov 14 12:11:38 2016 +0000
+++ b/test.html	Mon Nov 14 14:17:03 2016 +0000
@@ -1,41 +1,43 @@
 <!DOCTYPE html>
 <html lang="en">
-	<head>
-		<meta http-equiv="content-type" content="text/html; charset=utf-8">
 
+<head>
+    <meta http-equiv="content-type" content="text/html; charset=utf-8">
 
-		<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
+
+    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
 		Remove this if you use the .htaccess -->
-		<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
 
-		<title>Web Audio Evaluation Tool</title>
-		<meta name="description" content="" />
-		<meta name="author" content="" />
-		
-		<!-- Load up the default core JS and CSS files-->
-		<link rel='stylesheet' type='text/css' href='css/core.css'>
-		<!-- Use jQuery hosted from Google CDN -->
-		<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
-		<script type="text/javascript" src="js/jquery-2.1.4.js"></script>
-        <script type="text/javascript" src="js/loader.js"></script>
-	</head>
+    <title>Web Audio Evaluation Tool</title>
+    <meta name="description" content="" />
+    <meta name="author" content="" />
 
-	<body>
-		<!-- Load up the default page interface allowing for project setting loads, even if hard-coded-->
-		<!-- Actual test interface design should be contained in the .js for ease of dynamic content-->
-		<div id='topLevelBody'>
-            <span>Web Audio Evaluation Toolbox</span>
-		</div>
-        <div id="popupHolder" class="popupHolder" style="visibility: hidden">
-            <div id="popupContent">
-                <div id="popupTitleHolder">
-                    <span id="popupTitle"></span>
-                </div>
-                <div id="popupResponse"></div>
+    <!-- Load up the default core JS and CSS files-->
+    <link rel='stylesheet' type='text/css' href='css/core.css'>
+    <!-- Use jQuery hosted from Google CDN -->
+    <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>-->
+    <script type="text/javascript" src="js/jquery-2.1.4.js"></script>
+    <script type="text/javascript" src="js/loader.js"></script>
+</head>
+
+<body>
+    <!-- Load up the default page interface allowing for project setting loads, even if hard-coded-->
+    <!-- Actual test interface design should be contained in the .js for ease of dynamic content-->
+    <div id='topLevelBody'>
+        <span>Web Audio Evaluation Toolbox</span>
+    </div>
+    <div id="popupHolder" class="popupHolder" style="visibility: hidden">
+        <div id="popupContent">
+            <div id="popupTitleHolder">
+                <span id="popupTitle"></span>
             </div>
-            <button id="popup-proceed" class="popupButton">Next</button>
-            <button id="popup-previous" class="popupButton">Back</button>
+            <div id="popupResponse"></div>
         </div>
-        <div class="testHalt" style="visibility: hidden"></div>
-	</body>
+        <button id="popup-proceed" class="popupButton">Next</button>
+        <button id="popup-previous" class="popupButton">Back</button>
+    </div>
+    <div class="testHalt" style="visibility: hidden"></div>
+</body>
+
 </html>
--- a/test_create.html	Mon Nov 14 12:11:38 2016 +0000
+++ b/test_create.html	Mon Nov 14 14:17:03 2016 +0000
@@ -1,20 +1,31 @@
 <html>
+
 <head>
     <meta http-equiv="content-type" content="text/html; charset=utf-8">
     <!-- This defines the test creator tool for the Web Audio Evaluation Toolbox -->
-    <link rel='stylesheet' type="text/css" href="test_create/style.css"/>
-    <link rel='stylesheet' type="text/css" href="test_create/custom.css"/>
+    <link rel='stylesheet' type="text/css" href="test_create/style.css" />
+    <link rel='stylesheet' type="text/css" href="test_create/custom.css" />
     <script type="text/javascript">
-        window.onbeforeunload = function (e) {var message = 'If you leave the page now, any unsaved changes will be lost', e = e || window.event; if (e) { e.returnValue = message;}return message;};
+        window.onbeforeunload = function(e) {
+            var message = 'If you leave the page now, any unsaved changes will be lost',
+                e = e || window.event;
+            if (e) {
+                e.returnValue = message;
+            }
+            return message;
+        };
         // Copy of Specifiation node from Core.js
+
     </script>
     <script src="js/jquery-2.1.4.js"></script>
     <script type="text/javascript" src='js/specification.js'></script>
     <script type="text/javascript" src="test_create/test_core.js"></script>
 </head>
+
 <body>
     <div id="popupHolder"></div>
     <div id="blanket"></div>
     <div id="content"></div>
 </body>
+
 </html>
--- a/test_create/custom.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/test_create/custom.css	Mon Nov 14 14:17:03 2016 +0000
@@ -1,23 +1,20 @@
-
-div#content > div.node{
-    background-color: rgb(200,228,151);
+div#content > div.node {
+    background-color: rgb(200, 228, 151);
 }
-
-div#content > div#setup{
+div#content > div#setup {
     background-color: coral;
 }
-
-input:disabled+span{
+input:disabled+span {
     text-decoration: line-through;
 }
-
-div.attribute{
+div.attribute {
     float: none;
 }
-div.attribute input{
+div.attribute input {
     max-width: 100%;
     width: 300px;
 }
-div.attribute input[type=radio], div.attribute input[type=checkbox]{
+div.attribute input[type=radio],
+div.attribute input[type=checkbox] {
     width: 10px;
-}
\ No newline at end of file
+}
--- a/test_create/interface-specs.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/test_create/interface-specs.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,532 +1,532 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<root>
-    <global>
-        <metrics>
-            <list name="testTimer">Test Timer</list>
-            <list name="elementTimer">Element Playback Timer</list>
-            <list name="elementInitialPosition">Element Initial Position</list>
-            <list name="elementTracker">Element Movement Tracker</list>
-            <list name="elementFlagListenedTo">Element Listened to Flag</list>
-            <list name="elementFlagMoved">Element Moved Flag</list>
-            <list name="elementListenTracker">Element Listen Tracker</list>
-        </metrics>
-        <checks>
-            <list name="fragmentMoved">Check all moved</list>
-            <list name="fragmentPlayed">Check all played</list>
-            <list name="fragmentFullPlayback">Check all fully played (non-loop only)</list>
-            <list name="fragmentComments">Check comments entered</list>
-            <list name="scalerange">Enforce scale usage range</list>
-        </checks>
-        <show>
-            <list name="volume">Show master volume control</list>
-            <list name="page-count">Show test page count</list>
-            <list name="playhead">Show playhead</list>
-            <list name="comments">Show element comment boxes</list>
-        </show>
-    </global>
-    <interfaces>
-        <interface name="APE">
+    <root>
+        <global>
             <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="optional" default="on"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="optional" default="on"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
+                <list name="testTimer">Test Timer</list>
+                <list name="elementTimer">Element Playback Timer</list>
+                <list name="elementInitialPosition">Element Initial Position</list>
+                <list name="elementTracker">Element Movement Tracker</list>
+                <list name="elementFlagListenedTo">Element Listened to Flag</list>
+                <list name="elementFlagMoved">Element Moved Flag</list>
+                <list name="elementListenTracker">Element Listen Tracker</list>
             </metrics>
             <checks>
-                <entry name="fragmentMoved" support="optional" default="off"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="optional" default="off"/>
+                <list name="fragmentMoved">Check all moved</list>
+                <list name="fragmentPlayed">Check all played</list>
+                <list name="fragmentFullPlayback">Check all fully played (non-loop only)</list>
+                <list name="fragmentComments">Check comments entered</list>
+                <list name="scalerange">Enforce scale usage range</list>
             </checks>
             <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="on"/>
+                <list name="volume">Show master volume control</list>
+                <list name="page-count">Show test page count</list>
+                <list name="playhead">Show playhead</list>
+                <list name="comments">Show element comment boxes</list>
             </show>
-            <elements>
-                <number min="1" max="undefined"/>
-                <anchor min="0" max="undefined"/>
-                <reference min="0" max="undefined"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </interface>
-        <interface name="MUSHRA">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="optional" default="on"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="optional" default="on"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="optional" default="off"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="optional" default="off"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="1" max="undefined"/>
-                <anchor min="0" max="undefined"/>
-                <reference min="0" max="undefined"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </interface>
-        <interface name="horizontal">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="optional" default="on"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="optional" default="on"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="optional" default="off"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="optional" default="off"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="1" max="undefined"/>
-                <anchor min="0" max="undefined"/>
-                <reference min="0" max="undefined"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </interface>
-        <interface name="discrete">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="none"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="optional" default="on"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="mandatory"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="1" max="undefined"/>
-                <anchor min="0" max="undefined"/>
-                <reference min="0" max="undefined"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </interface>
-        <interface name="AB">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="none"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="none"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="2" max="undefined"/>
-                <anchor min="0" max="undefined"/>
-                <reference min="0" max="undefined"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </interface>
-        <interface name="ABX">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="none"/>
-                <entry name="elementTracker" support="optional" default="on"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="none"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="optional" default="off"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="2" max="2"/>
-                <anchor min="0" max="0"/>
-                <reference min="0" max="0"/>
-                <outsidereference min="0" max="0"/>
-            </elements>
-        </interface>
-        <interface name="timeline">
-            <metrics>
-                <entry name="testTimer" support="optional" default="on"/>
-                <entry name="elementTimer" support="optional" default="on"/>
-                <entry name="elementInitialPosition" support="none"/>
-                <entry name="elementTracker" support="none" default="off"/>
-                <entry name="elementFlagListenedTo" support="optional" default="on"/>
-                <entry name="elementFlagMoved" support="none"/>
-                <entry name="elementListenTracker" support="optional" default="on"/>
-            </metrics>
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="optional" default="off"/>
-                <entry name="fragmentFullPlayback" support="optional" default="off"/>
-                <entry name="fragmentComments" support="optional" default="off"/>
-                <entry name="scalerange" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="optional" default="off"/>
-                <entry name="page-count" support="optional" default="off"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="optional" default="off"/>
-            </show>
-            <elements>
-                <number min="1" max="undefined"/>
-                <anchor min="0" max="0"/>
-                <reference min="0" max="0"/>
-                <outsidereference min="0" max="undefined"/>
-            </elements>
-        </interface>
-    </interfaces>
-    <scaledefinitions>
-        <scale name="(Blank)">
-        </scale>
-        <scale name="Likert">
-            <scalelabel position="0">Strongly Disagree</scalelabel>
-            <scalelabel position="25">Disagree</scalelabel>
-            <scalelabel position="50">Neutral</scalelabel>
-            <scalelabel position="75">Agree</scalelabel>
-            <scalelabel position="100">Strongly Agree</scalelabel>
-        </scale>
-        <scale name="ABC">
-            <scalelabel position="100">Imperceptible</scalelabel>
-            <scalelabel position="75">Perceptible but not annoying</scalelabel>
-            <scalelabel position="50">Slightly annoying</scalelabel>
-            <scalelabel position="25">Annoying</scalelabel>
-            <scalelabel position="0">Very annoying</scalelabel>
-        </scale>
-        <scale name="Bipolar">
-            <scalelabel position="0">-50</scalelabel>
-            <scalelabel position="50">0</scalelabel>
-            <scalelabel position="100">50</scalelabel>
-        </scale>
-        <scale name="ACR">
-            <scalelabel position="0">Bad</scalelabel>
-            <scalelabel position="25">Poor</scalelabel>
-            <scalelabel position="50">Fair</scalelabel>
-            <scalelabel position="75">Good</scalelabel>
-            <scalelabel position="100">Excellent</scalelabel>
-        </scale>
-        <scale name="DCR">
-            <scalelabel position="0">(1) Very Annoying</scalelabel>
-            <scalelabel position="25">(2) Annoying</scalelabel>
-            <scalelabel position="50">(3) Slightly Annoying</scalelabel>
-            <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
-            <scalelabel position="100">(5) Inaudible</scalelabel>
-        </scale>
-        <scale name="CCR">
-            <scalelabel position="12">Much Worse</scalelabel>
-            <scalelabel position="25">Worse</scalelabel>
-            <scalelabel position="38">Slightly Worse</scalelabel>
-            <scalelabel position="50">About the same</scalelabel>
-            <scalelabel position="62">Slightly Better</scalelabel>
-            <scalelabel position="75">Better</scalelabel>
-            <scalelabel position="88">Much Better</scalelabel>
-        </scale>
-        <scale name="HCRS">
-            <scalelabel position="10">Dislike Extremely</scalelabel>
-            <scalelabel position="20">Dislike Very Much</scalelabel>
-            <scalelabel position="30">Dislike Moderate</scalelabel>
-            <scalelabel position="40">Dislike Slightly</scalelabel>
-            <scalelabel position="50">Neither Like nor Dislike</scalelabel>
-            <scalelabel position="60">Like Slightly</scalelabel>
-            <scalelabel position="70">Like Moderate</scalelabel>
-            <scalelabel position="80">Like Very Much</scalelabel>
-            <scalelabel position="90">Like Extremely</scalelabel>
-        </scale>
-    </scaledefinitions>
-    <tests>
-        <test name="APE" interface="APE">
-            <descriptions>
-                <description lang="en">Audio Perceptual Evaluation. A multi-stimulus test where each audio fragment is shown on one continuous slider. Fragments are randomnly positioned along the slider. The user clicks a fragment to play and drags to move.</description>
-            </descriptions>
-        </test>
-        <test name="vertical-sliders" interface="MUSHRA">
-            <descriptions>
-                <description lang="en">Each element is given its own vertical slider with user defined scale markers.</description>
-            </descriptions>
-        </test>
-        <test name="horizontal-sliders" interface="horizontal">
-            <descriptions>
-                <description lang="en">Each element is given its own horizontal slider with user defined scale markers.</description>
-            </descriptions>
-        </test>
-        <test name="discrete" interface="discrete">
-            <descriptions>
-                <description lang="en">Each element is given a horizontal scale broken into a number of discrete choices. The number of choices is defined by the scale markers.</description>
-            </descriptions>
-        </test>
-        <test name="Comparison" interface="AB">
-            <descriptions>
-                <description lang="en">An N-way comparison test. Each element is given its own selector box. The user can select one element per page for submission.</description>
-            </descriptions>
-        </test>
-        <test name="MUSHRA" interface="MUSHRA">
-            <descriptions>
-                <description lang="en">Multi-stimulus with hidden reference and anchor. Each fragment is shown on its own vertical slider. One fragment must be labelled as a reference and another labelled as an anchor. One external reference must also be shown.</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-                <entry name="scalerange" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <elements>
-                <anchor min="1" max="undefined"/>
-                <reference min="1" max="undefined"/>
-                <outsidereference min="1" max="1"/>
-            </elements>
-            <scale name="ACR"/>
-        </test>
-        <test name="Rank" interface="discrete">
-            <descriptions>
-                <description lang="en">Each stimulus is placed on a discrete scale equalling the number of fragments. The fragments are then ranked based on the question posed. Only one element can occupy a rank position</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="undefined"/>
-        </test>
-        <test name="Likert" interface="discrete">
-            <descriptions>
-                <description lang="en">Each stimulus is placed on a discrete scale. The scale is fixed to the Likert scale options of 'Strongly Disagree', 'Disagree', 'Neutral', 'Agree' and 'Strongly Agree'</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="Likert"/>
-        </test>
-        <test name="ABC/HR" interface="MUSHRA">
-            <descriptions>
-                <description lang="en">Each stimulus is placed on a vertical slider. The scale is fixed with the labels 'Imperceptible' to 'Very Annoying'</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="ABC"/>
-        </test>
-        <test name="Bipolar" interface="horizontal">
-            <descriptions>
-                <description lang="en">Each stimulus is placed on a horizontal slider and initialised to the value '0'. The scale operates from -50 to +5-. In the results this is normalised, like all other interfaces, from 0 (-50) to 1 (+50).</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentMoved" support="mandatory"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <elements>
-                <outsidereference min="1" max="1"/>
-            </elements>
-            <scale name="Bipolar"/>
-        </test>
-        <test name="ACR" interface="discrete">
-            <descriptions>
-                <description lang="en">Absolute Category Rating. Each element is on a discrete scale of 'Bad', 'Poor', 'Fair', 'Good' and 'Excellent'. Each element must be given a rating.</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentMoved" support="mandatory"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="ACR"/>
-        </test>
-        <test name="DCR" interface="discrete">
-            <checks>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="DCR"/>
-        </test>
-        <test name="CCR" interface="discrete">
-            <checks>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <scale name="CCR"/>
-        </test>
-        <test name="HCRS" interface="MUSHRA">
-            <checks>
-                <entry name="fragmentMoved" support="mandatory"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <elements>
-                <outsidereference min="1" max="1"/>
-            </elements>
-            <scale name="HCRS"/>
-        </test>
-        <test name="ITUR5PCIS" interface="MUSHRA">
-            <checks>
-                <entry name="fragmentMoved" support="none"/>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <elements>
-                <outsidereference min="1" max="1"/>
-            </elements>
-            <scale name="ABC"/>
-        </test>
-        <test name="AB" interface="AB">
-            <descriptions>
-                <description lang="en">Each page has only two audio fragments. The user must select one of the two fragments to proceed. There can be one hidden reference.</description>
-            </descriptions>
-            <checks>
-                <entry name="fragmentPlayed" support="none"/>
-                <entry name="fragmentFullPlayback" support="none"/>
-                <entry name="fragmentComments" support="none"/>
-            </checks>
-            <show>
-                <entry name="volume" support="none"/>
-                <entry name="page-count" support="none"/>
-                <entry name="playhead" support="none"/>
-                <entry name="comments" support="none"/>
-            </show>
-            <elements>
-                <number min="2" max="2"/>
-                <outsidereference min="0" max="1"/>
-            </elements>
-        </test>
-        <test name="ABX" interface="ABX">
-            <descriptions>
-                <description lang="en">Each page has two audio fragments presented as A and B. The test duplicates one of the fragments and presents it as X. The user must choose which, out of A or B, is closest to X.</description>
-            </descriptions>
-        </test>
-        <test name="timeline" interface="timeline">
-            <descriptions>
-                <description lang="en">Each fragment is displayed with a clickable waveform of itself. The user must click on the waveform at the location that a specific event occured. Users can then enter in information about this event. This test is unit-/value-less.</description>
-            </descriptions>
-        </test>
-    </tests>
-</root>
\ No newline at end of file
+        </global>
+        <interfaces>
+            <interface name="APE">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="optional" default="on" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="optional" default="on" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="optional" default="off" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="optional" default="off" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="on" />
+                </show>
+                <elements>
+                    <number min="1" max="undefined" />
+                    <anchor min="0" max="undefined" />
+                    <reference min="0" max="undefined" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </interface>
+            <interface name="MUSHRA">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="optional" default="on" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="optional" default="on" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="optional" default="off" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="optional" default="off" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="1" max="undefined" />
+                    <anchor min="0" max="undefined" />
+                    <reference min="0" max="undefined" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </interface>
+            <interface name="horizontal">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="optional" default="on" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="optional" default="on" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="optional" default="off" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="optional" default="off" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="1" max="undefined" />
+                    <anchor min="0" max="undefined" />
+                    <reference min="0" max="undefined" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </interface>
+            <interface name="discrete">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="none" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="optional" default="on" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="mandatory" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="1" max="undefined" />
+                    <anchor min="0" max="undefined" />
+                    <reference min="0" max="undefined" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </interface>
+            <interface name="AB">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="none" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="none" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="2" max="undefined" />
+                    <anchor min="0" max="undefined" />
+                    <reference min="0" max="undefined" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </interface>
+            <interface name="ABX">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="none" />
+                    <entry name="elementTracker" support="optional" default="on" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="none" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="optional" default="off" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="2" max="2" />
+                    <anchor min="0" max="0" />
+                    <reference min="0" max="0" />
+                    <outsidereference min="0" max="0" />
+                </elements>
+            </interface>
+            <interface name="timeline">
+                <metrics>
+                    <entry name="testTimer" support="optional" default="on" />
+                    <entry name="elementTimer" support="optional" default="on" />
+                    <entry name="elementInitialPosition" support="none" />
+                    <entry name="elementTracker" support="none" default="off" />
+                    <entry name="elementFlagListenedTo" support="optional" default="on" />
+                    <entry name="elementFlagMoved" support="none" />
+                    <entry name="elementListenTracker" support="optional" default="on" />
+                </metrics>
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="optional" default="off" />
+                    <entry name="fragmentFullPlayback" support="optional" default="off" />
+                    <entry name="fragmentComments" support="optional" default="off" />
+                    <entry name="scalerange" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="optional" default="off" />
+                    <entry name="page-count" support="optional" default="off" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="optional" default="off" />
+                </show>
+                <elements>
+                    <number min="1" max="undefined" />
+                    <anchor min="0" max="0" />
+                    <reference min="0" max="0" />
+                    <outsidereference min="0" max="undefined" />
+                </elements>
+            </interface>
+        </interfaces>
+        <scaledefinitions>
+            <scale name="(Blank)">
+            </scale>
+            <scale name="Likert">
+                <scalelabel position="0">Strongly Disagree</scalelabel>
+                <scalelabel position="25">Disagree</scalelabel>
+                <scalelabel position="50">Neutral</scalelabel>
+                <scalelabel position="75">Agree</scalelabel>
+                <scalelabel position="100">Strongly Agree</scalelabel>
+            </scale>
+            <scale name="ABC">
+                <scalelabel position="100">Imperceptible</scalelabel>
+                <scalelabel position="75">Perceptible but not annoying</scalelabel>
+                <scalelabel position="50">Slightly annoying</scalelabel>
+                <scalelabel position="25">Annoying</scalelabel>
+                <scalelabel position="0">Very annoying</scalelabel>
+            </scale>
+            <scale name="Bipolar">
+                <scalelabel position="0">-50</scalelabel>
+                <scalelabel position="50">0</scalelabel>
+                <scalelabel position="100">50</scalelabel>
+            </scale>
+            <scale name="ACR">
+                <scalelabel position="0">Bad</scalelabel>
+                <scalelabel position="25">Poor</scalelabel>
+                <scalelabel position="50">Fair</scalelabel>
+                <scalelabel position="75">Good</scalelabel>
+                <scalelabel position="100">Excellent</scalelabel>
+            </scale>
+            <scale name="DCR">
+                <scalelabel position="0">(1) Very Annoying</scalelabel>
+                <scalelabel position="25">(2) Annoying</scalelabel>
+                <scalelabel position="50">(3) Slightly Annoying</scalelabel>
+                <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
+                <scalelabel position="100">(5) Inaudible</scalelabel>
+            </scale>
+            <scale name="CCR">
+                <scalelabel position="12">Much Worse</scalelabel>
+                <scalelabel position="25">Worse</scalelabel>
+                <scalelabel position="38">Slightly Worse</scalelabel>
+                <scalelabel position="50">About the same</scalelabel>
+                <scalelabel position="62">Slightly Better</scalelabel>
+                <scalelabel position="75">Better</scalelabel>
+                <scalelabel position="88">Much Better</scalelabel>
+            </scale>
+            <scale name="HCRS">
+                <scalelabel position="10">Dislike Extremely</scalelabel>
+                <scalelabel position="20">Dislike Very Much</scalelabel>
+                <scalelabel position="30">Dislike Moderate</scalelabel>
+                <scalelabel position="40">Dislike Slightly</scalelabel>
+                <scalelabel position="50">Neither Like nor Dislike</scalelabel>
+                <scalelabel position="60">Like Slightly</scalelabel>
+                <scalelabel position="70">Like Moderate</scalelabel>
+                <scalelabel position="80">Like Very Much</scalelabel>
+                <scalelabel position="90">Like Extremely</scalelabel>
+            </scale>
+        </scaledefinitions>
+        <tests>
+            <test name="APE" interface="APE">
+                <descriptions>
+                    <description lang="en">Audio Perceptual Evaluation. A multi-stimulus test where each audio fragment is shown on one continuous slider. Fragments are randomnly positioned along the slider. The user clicks a fragment to play and drags to move.</description>
+                </descriptions>
+            </test>
+            <test name="vertical-sliders" interface="MUSHRA">
+                <descriptions>
+                    <description lang="en">Each element is given its own vertical slider with user defined scale markers.</description>
+                </descriptions>
+            </test>
+            <test name="horizontal-sliders" interface="horizontal">
+                <descriptions>
+                    <description lang="en">Each element is given its own horizontal slider with user defined scale markers.</description>
+                </descriptions>
+            </test>
+            <test name="discrete" interface="discrete">
+                <descriptions>
+                    <description lang="en">Each element is given a horizontal scale broken into a number of discrete choices. The number of choices is defined by the scale markers.</description>
+                </descriptions>
+            </test>
+            <test name="Comparison" interface="AB">
+                <descriptions>
+                    <description lang="en">An N-way comparison test. Each element is given its own selector box. The user can select one element per page for submission.</description>
+                </descriptions>
+            </test>
+            <test name="MUSHRA" interface="MUSHRA">
+                <descriptions>
+                    <description lang="en">Multi-stimulus with hidden reference and anchor. Each fragment is shown on its own vertical slider. One fragment must be labelled as a reference and another labelled as an anchor. One external reference must also be shown.</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                    <entry name="scalerange" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <elements>
+                    <anchor min="1" max="undefined" />
+                    <reference min="1" max="undefined" />
+                    <outsidereference min="1" max="1" />
+                </elements>
+                <scale name="ACR" />
+            </test>
+            <test name="Rank" interface="discrete">
+                <descriptions>
+                    <description lang="en">Each stimulus is placed on a discrete scale equalling the number of fragments. The fragments are then ranked based on the question posed. Only one element can occupy a rank position</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="undefined" />
+            </test>
+            <test name="Likert" interface="discrete">
+                <descriptions>
+                    <description lang="en">Each stimulus is placed on a discrete scale. The scale is fixed to the Likert scale options of 'Strongly Disagree', 'Disagree', 'Neutral', 'Agree' and 'Strongly Agree'</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="Likert" />
+            </test>
+            <test name="ABC/HR" interface="MUSHRA">
+                <descriptions>
+                    <description lang="en">Each stimulus is placed on a vertical slider. The scale is fixed with the labels 'Imperceptible' to 'Very Annoying'</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="ABC" />
+            </test>
+            <test name="Bipolar" interface="horizontal">
+                <descriptions>
+                    <description lang="en">Each stimulus is placed on a horizontal slider and initialised to the value '0'. The scale operates from -50 to +5-. In the results this is normalised, like all other interfaces, from 0 (-50) to 1 (+50).</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentMoved" support="mandatory" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <elements>
+                    <outsidereference min="1" max="1" />
+                </elements>
+                <scale name="Bipolar" />
+            </test>
+            <test name="ACR" interface="discrete">
+                <descriptions>
+                    <description lang="en">Absolute Category Rating. Each element is on a discrete scale of 'Bad', 'Poor', 'Fair', 'Good' and 'Excellent'. Each element must be given a rating.</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentMoved" support="mandatory" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="ACR" />
+            </test>
+            <test name="DCR" interface="discrete">
+                <checks>
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="DCR" />
+            </test>
+            <test name="CCR" interface="discrete">
+                <checks>
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <scale name="CCR" />
+            </test>
+            <test name="HCRS" interface="MUSHRA">
+                <checks>
+                    <entry name="fragmentMoved" support="mandatory" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <elements>
+                    <outsidereference min="1" max="1" />
+                </elements>
+                <scale name="HCRS" />
+            </test>
+            <test name="ITUR5PCIS" interface="MUSHRA">
+                <checks>
+                    <entry name="fragmentMoved" support="none" />
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <elements>
+                    <outsidereference min="1" max="1" />
+                </elements>
+                <scale name="ABC" />
+            </test>
+            <test name="AB" interface="AB">
+                <descriptions>
+                    <description lang="en">Each page has only two audio fragments. The user must select one of the two fragments to proceed. There can be one hidden reference.</description>
+                </descriptions>
+                <checks>
+                    <entry name="fragmentPlayed" support="none" />
+                    <entry name="fragmentFullPlayback" support="none" />
+                    <entry name="fragmentComments" support="none" />
+                </checks>
+                <show>
+                    <entry name="volume" support="none" />
+                    <entry name="page-count" support="none" />
+                    <entry name="playhead" support="none" />
+                    <entry name="comments" support="none" />
+                </show>
+                <elements>
+                    <number min="2" max="2" />
+                    <outsidereference min="0" max="1" />
+                </elements>
+            </test>
+            <test name="ABX" interface="ABX">
+                <descriptions>
+                    <description lang="en">Each page has two audio fragments presented as A and B. The test duplicates one of the fragments and presents it as X. The user must choose which, out of A or B, is closest to X.</description>
+                </descriptions>
+            </test>
+            <test name="timeline" interface="timeline">
+                <descriptions>
+                    <description lang="en">Each fragment is displayed with a clickable waveform of itself. The user must click on the waveform at the location that a specific event occured. Users can then enter in information about this event. This test is unit-/value-less.</description>
+                </descriptions>
+            </test>
+        </tests>
+    </root>
--- a/test_create/style.css	Mon Nov 14 12:11:38 2016 +0000
+++ b/test_create/style.css	Mon Nov 14 14:17:03 2016 +0000
@@ -1,30 +1,27 @@
 div#blanket {
     z-index: 2;
-    background-color: rgba(0,0,0,0.5);
+    background-color: rgba(0, 0, 0, 0.5);
     width: 100%;
     height: 100%;
     position: fixed;
     left: 0px;
     top: 0px;
 }
-
 div#popupHolder {
     z-index: 3;
-    background-color: rgba(255,255,255,1);
+    background-color: rgba(255, 255, 255, 1);
     width: 730px;
     height: 480px;
     position: fixed;
     border-radius: 10px;
-	box-shadow: 0px 0px 50px #000;
+    box-shadow: 0px 0px 50px #000;
     padding: 10px;
 }
-
 div#popup-title-holder {
     width: 100%;
     height: 50px;
     font-size: 2em;
 }
-
 button.popup-button {
     width: 60px;
     height: 27px;
@@ -32,15 +29,12 @@
     position: absolute;
     bottom: 10px;
 }
-
 button#popup-proceed {
     right: 10px;
 }
-
 button#popup-back {
     left: 10px;
 }
-
 div.drag-area {
     border: 3px black dashed;
 }
@@ -53,40 +47,30 @@
 div.drag-error {
     background-color: coral
 }
-
 div#project-drop {
     width: 99%;
     height: 50px;
     margin: 10px 0px;
 }
-
 div.popup-checkbox {
     padding: 5px;
 }
-
 div.popup-checkbox input {
     margin: 0px 5px;
 }
-
 div.popup-option-entry {
     padding: 5px 0px;
     border-bottom: 1px solid;
 }
-
-div.disabled{
-    color: rgb(100,100,100);
+div.disabled {
+    color: rgb(100, 100, 100);
 }
-
-
-div#page-holder > div.node{
-    background-color: rgb(200,228,151);
+div#page-holder > div.node {
+    background-color: rgb(200, 228, 151);
 }
-
-div#content > div#setup{
+div#content > div#setup {
     background-color: coral;
 }
-
-
 div.node {
     float: left;
     padding: 10px;
@@ -94,7 +78,7 @@
     border-radius: 10px;
     margin: 10px;
     min-width: 92%;
-    background-color: rgba(255,255,255,0.5);
+    background-color: rgba(255, 255, 255, 0.5);
 }
 div.node-title {
     float: left;
@@ -127,13 +111,13 @@
 div.attribute input[type=number] {
     width: 80px;
 }
-div.attribute input[type=radio], div.attribute input[type=checkbox]{
+div.attribute input[type=radio],
+div.attribute input[type=checkbox] {
     width: 10px;
 }
-input:disabled+label{
+input:disabled+label {
     text-decoration: line-through;
 }
-
 div.survey-entry-attribute {
     margin: 10px 0px;
     border: 1px gray solid;
@@ -142,7 +126,6 @@
     line-height: 40px;
     padding: 0px 10px;
 }
-
-div.survey-entry-attribute span{
+div.survey-entry-attribute span {
     margin-right: 10px;
-}
\ No newline at end of file
+}
--- a/tests/examples/AB_example.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/AB_example.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,97 +1,97 @@
 <?xml version="1.0" encoding="utf-8"?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="AB" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" playOne="true">
-		<survey location="before">
-			<surveyentry type="question" id="sessionId" mandatory="true">
-				<statement>Please enter your name.</statement>
-			</surveyentry>
-			<surveyentry type="checkbox" id="checkboxtest" mandatory="true">
-				<statement>Please select with which activities you have any experience (example checkbox question)</statement>
-				<option name="musician">Playing a musical instrument</option>
-				<option name="soundengineer">Recording or mixing audio</option>
-				<option name="developer">Developing audio software</option>
-				<option name="hwdesigner">Designing or building audio hardware</option>
-				<option name="researcher">Research in the field of audio</option>
-			</surveyentry>
-			<surveyentry type="statement" id="test-intro">
-				<statement>This is an example of an 'AB'-style test, with two pages, using the test stimuli in 'example_eval/'. The 'playOne' configuration option means a fragment has to be finished playing before another fragment can be auditioned. </statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="location" mandatory="true" boxsize="large">
-				<statement>Please enter your location. (example mandatory text question)</statement>
-			</surveyentry>
-			<surveyentry type="number" id="age" min="0">
-				<statement>Please enter your age (example non-mandatory number question)</statement>
-			</surveyentry>
-			<surveyentry type="radio" id="rating">
-				<statement>Please rate this interface (example radio button question)</statement>
-				<option name="bad">Bad</option>
-				<option name="poor">Poor</option>
-				<option name="good">Good</option>
-				<option name="great">Great</option>
-			</surveyentry>
-			<surveyentry type="statement" id="test-thank-you">
-				<statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
-			</surveyentry>
-		</survey>
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentMoved"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name='volume'/>
-            <interfaceoption type="show" name='comments'/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' loudness="-12">
-		<commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface>
-			<title>Depth</title>
-		</interface>
-		<audioelement url="0.wav" id="track-0"/>
-		<audioelement url="1.wav" id="track-1"/>
-		<survey location="before">
-			<surveyentry type="statement" id="test-0-intro">
-				<statement>A two way comparison using randomised element order, automatic loudness and synchronised looping.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-0" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-	<page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' loudness="-12">
-		<commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface>
-			<title>Depth</title>
-		</interface>
-		<audioelement url="0.wav" id="track-2"/>
-		<audioelement url="1.wav" id="track-3"/>
-		<audioelement url="2.wav" id="track-4"/>
-		<audioelement url="3.wav" id="track-5"/>
-		<audioelement url="4.wav" id="track-6"/>
-		<audioelement url="5.wav" id="track-7"/>
-		<audioelement url="6.wav" id="track-8"/>
-		<survey location="before">
-			<surveyentry type="statement" id="test-1-intro">
-				<statement>A 7 way comparison using randomised element order and synchronised looping.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-1" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-</waet>
\ No newline at end of file
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="AB" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" playOne="true">
+            <survey location="before">
+                <surveyentry type="question" id="sessionId" mandatory="true">
+                    <statement>Please enter your name.</statement>
+                </surveyentry>
+                <surveyentry type="checkbox" id="checkboxtest" mandatory="true">
+                    <statement>Please select with which activities you have any experience (example checkbox question)</statement>
+                    <option name="musician">Playing a musical instrument</option>
+                    <option name="soundengineer">Recording or mixing audio</option>
+                    <option name="developer">Developing audio software</option>
+                    <option name="hwdesigner">Designing or building audio hardware</option>
+                    <option name="researcher">Research in the field of audio</option>
+                </surveyentry>
+                <surveyentry type="statement" id="test-intro">
+                    <statement>This is an example of an 'AB'-style test, with two pages, using the test stimuli in 'example_eval/'. The 'playOne' configuration option means a fragment has to be finished playing before another fragment can be auditioned. </statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="location" mandatory="true" boxsize="large">
+                    <statement>Please enter your location. (example mandatory text question)</statement>
+                </surveyentry>
+                <surveyentry type="number" id="age" min="0">
+                    <statement>Please enter your age (example non-mandatory number question)</statement>
+                </surveyentry>
+                <surveyentry type="radio" id="rating">
+                    <statement>Please rate this interface (example radio button question)</statement>
+                    <option name="bad">Bad</option>
+                    <option name="poor">Poor</option>
+                    <option name="good">Good</option>
+                    <option name="great">Great</option>
+                </surveyentry>
+                <surveyentry type="statement" id="test-thank-you">
+                    <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
+                </surveyentry>
+            </survey>
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name='volume' />
+                <interfaceoption type="show" name='comments' />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' loudness="-12">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface>
+                <title>Depth</title>
+            </interface>
+            <audioelement url="0.wav" id="track-0" />
+            <audioelement url="1.wav" id="track-1" />
+            <survey location="before">
+                <surveyentry type="statement" id="test-0-intro">
+                    <statement>A two way comparison using randomised element order, automatic loudness and synchronised looping.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-0" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+        <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' loudness="-12">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface>
+                <title>Depth</title>
+            </interface>
+            <audioelement url="0.wav" id="track-2" />
+            <audioelement url="1.wav" id="track-3" />
+            <audioelement url="2.wav" id="track-4" />
+            <audioelement url="3.wav" id="track-5" />
+            <audioelement url="4.wav" id="track-6" />
+            <audioelement url="5.wav" id="track-7" />
+            <audioelement url="6.wav" id="track-8" />
+            <survey location="before">
+                <surveyentry type="statement" id="test-1-intro">
+                    <statement>A 7 way comparison using randomised element order and synchronised looping.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-1" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+    </waet>
--- a/tests/examples/APE_example.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/APE_example.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,143 +1,143 @@
 <?xml version="1.0" encoding="utf-8"?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" calibration="true">
-		<survey location="before">
-			<surveyentry type="question" id="sessionId" mandatory="true">
-				<statement>Please enter your name.</statement>
-                <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest"/>
-			</surveyentry>
-			<surveyentry type="checkbox" id="checkboxtest" mandatory="true">
-				<statement>Please select with which activities you have any experience (example checkbox question)</statement>
-				<option name="musician">Playing a musical instrument</option>
-				<option name="soundengineer">Recording or mixing audio</option>
-				<option name="developer">Developing audio software</option>
-				<option name="hwdesigner">Designing or building audio hardware</option>
-				<option name="researcher">Research in the field of audio</option>
-			</surveyentry>
-            <surveyentry type="question" id="instrument" mandatory="false">
-                <statement>What instrument did you play</statement>
-            </surveyentry>
-			<surveyentry type="statement" id="test-intro">
-				<statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="location" mandatory="true" boxsize="large">
-				<statement>Please enter your location. (example mandatory text question)</statement>
-			</surveyentry>
-			<surveyentry type="number" id="age" min="0">
-				<statement>Please enter your age (example non-mandatory number question)</statement>
-			</surveyentry>
-			<surveyentry type="radio" id="rating">
-				<statement>Please rate this interface (example radio button question)</statement>
-				<option name="bad">Bad</option>
-				<option name="poor">Poor</option>
-				<option name="good">Good</option>
-				<option name="great">Great</option>
-			</surveyentry>
-			<surveyentry type="statement" id="thankyou">
-				<statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
-			</surveyentry>
-		</survey>
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentMoved"/>
-            <interfaceoption type="check" name="fragmentPlayed"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name="comments"/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
-		<commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface name="preference">
-            <title>Preference</title>
-			<scales>
-				<scalelabel position="0">Min</scalelabel>
-				<scalelabel position="100">Max</scalelabel>
-				<scalelabel position="50">Middle</scalelabel>
-				<scalelabel position="20">20</scalelabel>
-			</scales>
-		</interface>
-		<interface name="depth">
-			<title>Depth</title>
-			<scales>
-				<scalelabel position="0">Low</scalelabel>
-				<scalelabel position="100">High</scalelabel>
-				<scalelabel position="50">Middle</scalelabel>
-				<scalelabel position="50">Middle</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-0" type="anchor"/>
-		<audioelement url="1.wav" id="track-1"/>
-		<audioelement url="2.wav" id="track-2"/>
-		<audioelement url="3.wav" id="track-3"/>
-		<audioelement url="4.wav" id="track-4"/>
-		<survey location="before">
-			<surveyentry type="statement" id="test-0-intro">
-				<statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-0" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-	<page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' label="letter">
-        <commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface name="preference">
-			<title>Example Test Question</title>
-			<scales>
-				<scalelabel position="0">Min</scalelabel>
-				<scalelabel position="100">Max</scalelabel>
-				<scalelabel position="50">Middle</scalelabel>
-				<scalelabel position="20">20</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20"/>
-		<audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80"/>
-		<audioelement url="2.wav" gain="0.0" id="track-7"/>
-		<audioelement url="3.wav" gain="0.0" id="track-8"/>
-		<audioelement url="4.wav" gain="0.0" id="track-9"/>
-		<audioelement url="5.wav" gain="0.0" id="track-10"/>
-		<audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference"/>
-		<commentquestion id='mixingExperience' type="question">
-			<statement>What is your general experience with numbers?</statement>
-		</commentquestion>
-		<commentquestion id="preference" type="radio">
-			<statement>Please enter your overall preference</statement>
-			<option name="worst">Very Bad</option>
-			<option name="bad"></option>
-			<option name="OK">OK</option>
-			<option name="Good"></option>
-			<option name="Great">Great</option>
-		</commentquestion>
-		<commentquestion id="character" type="checkbox">
-			<statement>Please describe the overall character</statement>
-			<option name="funky">Funky</option>
-			<option name="mellow">Mellow</option>
-			<option name="laidback">Laid back</option>
-			<option name="heavy">Heavy</option>
-		</commentquestion>
-		<survey location="before">
-			<surveyentry type="statement" id="test-1-intro">
-				<statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-1" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-</waet>
\ No newline at end of file
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="APE" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23" calibration="true">
+            <survey location="before">
+                <surveyentry type="question" id="sessionId" mandatory="true">
+                    <statement>Please enter your name.</statement>
+                    <conditional check="equals" value="John" jumpToOnPass="test-intro" jumpToOnFail="checkboxtest" />
+                </surveyentry>
+                <surveyentry type="checkbox" id="checkboxtest" mandatory="true">
+                    <statement>Please select with which activities you have any experience (example checkbox question)</statement>
+                    <option name="musician">Playing a musical instrument</option>
+                    <option name="soundengineer">Recording or mixing audio</option>
+                    <option name="developer">Developing audio software</option>
+                    <option name="hwdesigner">Designing or building audio hardware</option>
+                    <option name="researcher">Research in the field of audio</option>
+                </surveyentry>
+                <surveyentry type="question" id="instrument" mandatory="false">
+                    <statement>What instrument did you play</statement>
+                </surveyentry>
+                <surveyentry type="statement" id="test-intro">
+                    <statement>This is an example of an 'APE'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="location" mandatory="true" boxsize="large">
+                    <statement>Please enter your location. (example mandatory text question)</statement>
+                </surveyentry>
+                <surveyentry type="number" id="age" min="0">
+                    <statement>Please enter your age (example non-mandatory number question)</statement>
+                </surveyentry>
+                <surveyentry type="radio" id="rating">
+                    <statement>Please rate this interface (example radio button question)</statement>
+                    <option name="bad">Bad</option>
+                    <option name="poor">Poor</option>
+                    <option name="good">Good</option>
+                    <option name="great">Great</option>
+                </surveyentry>
+                <surveyentry type="statement" id="thankyou">
+                    <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
+                </surveyentry>
+            </survey>
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="fragmentPlayed" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="comments" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface name="preference">
+                <title>Preference</title>
+                <scales>
+                    <scalelabel position="0">Min</scalelabel>
+                    <scalelabel position="100">Max</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="20">20</scalelabel>
+                </scales>
+            </interface>
+            <interface name="depth">
+                <title>Depth</title>
+                <scales>
+                    <scalelabel position="0">Low</scalelabel>
+                    <scalelabel position="100">High</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-0" type="anchor" />
+            <audioelement url="1.wav" id="track-1" />
+            <audioelement url="2.wav" id="track-2" />
+            <audioelement url="3.wav" id="track-3" />
+            <audioelement url="4.wav" id="track-4" />
+            <survey location="before">
+                <surveyentry type="statement" id="test-0-intro">
+                    <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-0" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+        <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false' label="letter">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface name="preference">
+                <title>Example Test Question</title>
+                <scales>
+                    <scalelabel position="0">Min</scalelabel>
+                    <scalelabel position="100">Max</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="20">20</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" gain="-6" id="track-5" type="anchor" marker="20" />
+            <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80" />
+            <audioelement url="2.wav" gain="0.0" id="track-7" />
+            <audioelement url="3.wav" gain="0.0" id="track-8" />
+            <audioelement url="4.wav" gain="0.0" id="track-9" />
+            <audioelement url="5.wav" gain="0.0" id="track-10" />
+            <audioelement url="6.wav" gain="0.0" id="track-11" type="outside-reference" />
+            <commentquestion id='mixingExperience' type="question">
+                <statement>What is your general experience with numbers?</statement>
+            </commentquestion>
+            <commentquestion id="preference" type="radio">
+                <statement>Please enter your overall preference</statement>
+                <option name="worst">Very Bad</option>
+                <option name="bad"></option>
+                <option name="OK">OK</option>
+                <option name="Good"></option>
+                <option name="Great">Great</option>
+            </commentquestion>
+            <commentquestion id="character" type="checkbox">
+                <statement>Please describe the overall character</statement>
+                <option name="funky">Funky</option>
+                <option name="mellow">Mellow</option>
+                <option name="laidback">Laid back</option>
+                <option name="heavy">Heavy</option>
+            </commentquestion>
+            <survey location="before">
+                <surveyentry type="statement" id="test-1-intro">
+                    <statement>Example of an 'APE' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-1" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+    </waet>
--- a/tests/examples/horizontal_example.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/horizontal_example.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,33 +1,33 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="ABC" projectReturn="save.php">
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentMoved"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name="volume"/>
-            <interfaceoption type="show" name="comments"/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
-		<interface>
-			<scales>
-				<scalelabel position="0">-50</scalelabel>
-				<scalelabel position="50">0</scalelabel>
-				<scalelabel position="100">50</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-1"/>
-		<audioelement url="1.wav" id="track-2"/>
-	</page>
-</waet>
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="ABC" projectReturn="save.php">
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="volume" />
+                <interfaceoption type="show" name="comments" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
+            <interface>
+                <scales>
+                    <scalelabel position="0">-50</scalelabel>
+                    <scalelabel position="50">0</scalelabel>
+                    <scalelabel position="100">50</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-1" />
+            <audioelement url="1.wav" id="track-2" />
+        </page>
+    </waet>
--- a/tests/examples/mushra_example.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/mushra_example.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,133 +1,133 @@
 <?xml version="1.0" encoding="utf-8"?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="MUSHRA" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23">
-        <exitText>Thank you for looking at WAET. You can modify the successful completion text as well!</exitText>
-		<survey location="before">
-			<surveyentry type="question" id="sessionId" mandatory="true">
-				<statement>Please enter your name.</statement>
-			</surveyentry>
-			<surveyentry type="checkbox" id="checkboxtest" mandatory="true">
-				<statement>Please select with which activities you have any experience (example checkbox question)</statement>
-				<option name="musician">Playing a musical instrument</option>
-				<option name="soundengineer">Recording or mixing audio</option>
-				<option name="developer">Developing audio software</option>
-				<option name="hwdesigner">Designing or building audio hardware</option>
-				<option name="researcher">Research in the field of audio</option>
-			</surveyentry>
-			<surveyentry type="statement" id="test-intro">
-				<statement>This is an example of an 'MUSHRA'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="location" mandatory="true" boxsize="large">
-				<statement>Please enter your location. (example mandatory text question)</statement>
-			</surveyentry>
-			<surveyentry type="number" id="age" min="0">
-				<statement>Please enter your age (example non-mandatory number question)</statement>
-			</surveyentry>
-			<surveyentry type="radio" id="rating">
-				<statement>Please rate this interface (example radio button question)</statement>
-				<option name="bad">Bad</option>
-				<option name="poor">Poor</option>
-				<option name="good">Good</option>
-				<option name="great">Great</option>
-			</surveyentry>
-			<surveyentry type="statement" id="thankyou">
-				<statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
-			</surveyentry>
-		</survey>
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentMoved"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name="volume"/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
-		<commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface>
-			<scales>
-				<scalelabel position="12">Much Worse</scalelabel>
-				<scalelabel position="25">Worse</scalelabel>
-				<scalelabel position="38">Slightly Worse</scalelabel>
-				<scalelabel position="50">About the same</scalelabel>
-				<scalelabel position="62">Slightly Better</scalelabel>
-				<scalelabel position="75">Better</scalelabel>
-				<scalelabel position="88">Much Better</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-0" type="anchor"/>
-		<audioelement url="1.wav" id="track-1"/>
-		<audioelement url="2.wav" id="track-2"/>
-		<audioelement url="3.wav" id="track-3"/>
-		<audioelement url="4.wav" id="track-4"/>
-		<survey location="before">
-			<surveyentry type="statement" id="test-0-intro">
-				<statement>Example of a 'MUSHRA' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75% using a Comparison Category Rating Scale.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-0" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-	<page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false'>
-		<commentboxprefix>Comment on fragment</commentboxprefix>
-		<interface name="preference">
-			<title>Example Test Question</title>
-            <interfaceoption type="show" name="comments"/>
-			<scales>
-				<scalelabel position="0">Min</scalelabel>
-				<scalelabel position="100">Max</scalelabel>
-				<scalelabel position="50">Middle</scalelabel>
-				<scalelabel position="20">20</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" gain="-6.0" id="track-5" type="anchor" marker="20"/>
-		<audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80"/>
-		<audioelement url="2.wav" gain="0.0" id="track-7"/>
-		<audioelement url="3.wav" gain="0.0" id="track-8"/>
-		<audioelement url="4.wav" gain="0.0" id="track-9"/>
-		<audioelement url="5.wav" gain="0.0" id="track-10"/>
-		<audioelement url="1.wav" gain="0.0" id="track-11" type="outside-reference"/>
-		<commentquestion id='mixingExperience' type="question">
-			<statement>What is your general experience with numbers?</statement>
-		</commentquestion>
-		<commentquestion id="preference" type="radio">
-			<statement>Please enter your overall preference</statement>
-			<option name="worst">Very Bad</option>
-			<option name="bad"></option>
-			<option name="OK">OK</option>
-			<option name="Good"></option>
-			<option name="Great">Great</option>
-		</commentquestion>
-		<commentquestion id="character" type="checkbox">
-			<statement>Please describe the overall character</statement>
-			<option name="funky">Funky</option>
-			<option name="mellow">Mellow</option>
-			<option name="laidback">Laid back</option>
-			<option name="heavy">Heavy</option>
-		</commentquestion>
-		<survey location="before">
-			<surveyentry type="statement" id="test-1-intro">
-				<statement>Example of a 'MUSHRA' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
-			</surveyentry>
-		</survey>
-		<survey location="after">
-			<surveyentry type="question" id="genre-1" mandatory="true">
-				<statement>Please enter the genre.</statement>
-			</surveyentry>
-		</survey>
-	</page>
-</waet>
\ No newline at end of file
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="MUSHRA" projectReturn="save.php" randomiseOrder='true' poolSize="2" loudness="-23">
+            <exitText>Thank you for looking at WAET. You can modify the successful completion text as well!</exitText>
+            <survey location="before">
+                <surveyentry type="question" id="sessionId" mandatory="true">
+                    <statement>Please enter your name.</statement>
+                </surveyentry>
+                <surveyentry type="checkbox" id="checkboxtest" mandatory="true">
+                    <statement>Please select with which activities you have any experience (example checkbox question)</statement>
+                    <option name="musician">Playing a musical instrument</option>
+                    <option name="soundengineer">Recording or mixing audio</option>
+                    <option name="developer">Developing audio software</option>
+                    <option name="hwdesigner">Designing or building audio hardware</option>
+                    <option name="researcher">Research in the field of audio</option>
+                </surveyentry>
+                <surveyentry type="statement" id="test-intro">
+                    <statement>This is an example of an 'MUSHRA'-style test, with two pages, using the test stimuli in 'example_eval/'.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="location" mandatory="true" boxsize="large">
+                    <statement>Please enter your location. (example mandatory text question)</statement>
+                </surveyentry>
+                <surveyentry type="number" id="age" min="0">
+                    <statement>Please enter your age (example non-mandatory number question)</statement>
+                </surveyentry>
+                <surveyentry type="radio" id="rating">
+                    <statement>Please rate this interface (example radio button question)</statement>
+                    <option name="bad">Bad</option>
+                    <option name="poor">Poor</option>
+                    <option name="good">Good</option>
+                    <option name="great">Great</option>
+                </surveyentry>
+                <surveyentry type="statement" id="thankyou">
+                    <statement>Thank you for taking this listening test. Please click 'submit' and your results will appear in the 'saves/' folder.</statement>
+                </surveyentry>
+            </survey>
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="volume" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='true' loudness="-12">
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface>
+                <scales>
+                    <scalelabel position="12">Much Worse</scalelabel>
+                    <scalelabel position="25">Worse</scalelabel>
+                    <scalelabel position="38">Slightly Worse</scalelabel>
+                    <scalelabel position="50">About the same</scalelabel>
+                    <scalelabel position="62">Slightly Better</scalelabel>
+                    <scalelabel position="75">Better</scalelabel>
+                    <scalelabel position="88">Much Better</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-0" type="anchor" />
+            <audioelement url="1.wav" id="track-1" />
+            <audioelement url="2.wav" id="track-2" />
+            <audioelement url="3.wav" id="track-3" />
+            <audioelement url="4.wav" id="track-4" />
+            <survey location="before">
+                <surveyentry type="statement" id="test-0-intro">
+                    <statement>Example of a 'MUSHRA' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75% using a Comparison Category Rating Scale.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-0" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+        <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='0' loop='false'>
+            <commentboxprefix>Comment on fragment</commentboxprefix>
+            <interface name="preference">
+                <title>Example Test Question</title>
+                <interfaceoption type="show" name="comments" />
+                <scales>
+                    <scalelabel position="0">Min</scalelabel>
+                    <scalelabel position="100">Max</scalelabel>
+                    <scalelabel position="50">Middle</scalelabel>
+                    <scalelabel position="20">20</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" gain="-6.0" id="track-5" type="anchor" marker="20" />
+            <audioelement url="1.wav" gain="0.0" id="track-6" type="reference" marker="80" />
+            <audioelement url="2.wav" gain="0.0" id="track-7" />
+            <audioelement url="3.wav" gain="0.0" id="track-8" />
+            <audioelement url="4.wav" gain="0.0" id="track-9" />
+            <audioelement url="5.wav" gain="0.0" id="track-10" />
+            <audioelement url="1.wav" gain="0.0" id="track-11" type="outside-reference" />
+            <commentquestion id='mixingExperience' type="question">
+                <statement>What is your general experience with numbers?</statement>
+            </commentquestion>
+            <commentquestion id="preference" type="radio">
+                <statement>Please enter your overall preference</statement>
+                <option name="worst">Very Bad</option>
+                <option name="bad"></option>
+                <option name="OK">OK</option>
+                <option name="Good"></option>
+                <option name="Great">Great</option>
+            </commentquestion>
+            <commentquestion id="character" type="checkbox">
+                <statement>Please describe the overall character</statement>
+                <option name="funky">Funky</option>
+                <option name="mellow">Mellow</option>
+                <option name="laidback">Laid back</option>
+                <option name="heavy">Heavy</option>
+            </commentquestion>
+            <survey location="before">
+                <surveyentry type="statement" id="test-1-intro">
+                    <statement>Example of a 'MUSHRA' style interface with hidden anchor 'zero' (which needs to be below 20%), looping of the samples, randomisation of marker labels, mandatory moving of every sample, and a forced scale usage of at least 25%-75%.</statement>
+                </surveyentry>
+            </survey>
+            <survey location="after">
+                <surveyentry type="question" id="genre-1" mandatory="true">
+                    <statement>Please enter the genre.</statement>
+                </surveyentry>
+            </survey>
+        </page>
+    </waet>
--- a/tests/examples/radio_example.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/radio_example.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,37 +1,37 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="likert" projectReturn="save.php" crossFade="3.0">
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentMoved"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-            <interfaceoption type="show" name="volume"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name="comments"/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
-		<interface>
-			<scales>
-				<scalelabel position="0">(1) Very Annoying</scalelabel>
-				<scalelabel position="25">(2) Annoying</scalelabel>
-				<scalelabel position="50">(3) Slightly Annoying</scalelabel>
-				<scalelabel position="75">(4) Audible but not Annoying</scalelabel>
-				<scalelabel position="100">(5) Inaudible</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-1" alwaysInclude="true"/>
-		<audioelement url="1.wav" id="track-2"/>
-        <audioelement url="3.wav" id="track-4"/>
-        <audioelement url="3.wav" id="track-5"/>
-	</page>
-</waet>
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="likert" projectReturn="save.php" crossFade="3.0">
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentMoved" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name="volume" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="comments" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
+            <interface>
+                <scales>
+                    <scalelabel position="0">(1) Very Annoying</scalelabel>
+                    <scalelabel position="25">(2) Annoying</scalelabel>
+                    <scalelabel position="50">(3) Slightly Annoying</scalelabel>
+                    <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
+                    <scalelabel position="100">(5) Inaudible</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-1" alwaysInclude="true" />
+            <audioelement url="1.wav" id="track-2" />
+            <audioelement url="3.wav" id="track-4" />
+            <audioelement url="3.wav" id="track-5" />
+        </page>
+    </waet>
--- a/tests/examples/timeline.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/tests/examples/timeline.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,80 +1,80 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
-	<setup interface="timeline" projectReturn="save.php">
-		<metric>
-			<metricenable>testTimer</metricenable>
-			<metricenable>elementTimer</metricenable>
-			<metricenable>elementInitialPosition</metricenable>
-			<metricenable>elementTracker</metricenable>
-			<metricenable>elementFlagListenedTo</metricenable>
-			<metricenable>elementFlagMoved</metricenable>
-			<metricenable>elementListenTracker</metricenable>
-		</metric>
-		<interface>
-			<interfaceoption type="check" name="fragmentPlayed"/>
-			<interfaceoption type="check" name="scalerange" min="25" max="75"/>
-            <interfaceoption type="show" name="volume"/>
-			<interfaceoption type="show" name='playhead'/>
-			<interfaceoption type="show" name="page-count"/>
-            <interfaceoption type="show" name="comments"/>
-		</interface>
-	</setup>
-	<page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
-        <title>My Test</title>
-		<interface>
-			<scales>
-				<scalelabel position="0">(1) Very Annoying</scalelabel>
-				<scalelabel position="25">(2) Annoying</scalelabel>
-				<scalelabel position="50">(3) Slightly Annoying</scalelabel>
-				<scalelabel position="75">(4) Audible but not Annoying</scalelabel>
-				<scalelabel position="100">(5) Inaudible</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-1"/>
-		<audioelement url="1.wav" id="track-2"/>
-        <commentquestion id="preference" type="radio">
-			<statement>Please enter your overall preference</statement>
-			<option name="worst">Very Bad</option>
-			<option name="bad"></option>
-			<option name="OK">OK</option>
-			<option name="Good"></option>
-			<option name="Great">Great</option>
-		</commentquestion>
-		<commentquestion id="character" type="checkbox">
-			<statement>Please describe the overall character</statement>
-			<option name="funky">Funky</option>
-			<option name="mellow">Mellow</option>
-			<option name="laidback">Laid back</option>
-			<option name="heavy">Heavy</option>
-		</commentquestion>
-	</page>
-    <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
-        <title>My Test</title>
-		<interface>
-			<scales>
-				<scalelabel position="0">(1) Very Annoying</scalelabel>
-				<scalelabel position="25">(2) Annoying</scalelabel>
-				<scalelabel position="50">(3) Slightly Annoying</scalelabel>
-				<scalelabel position="75">(4) Audible but not Annoying</scalelabel>
-				<scalelabel position="100">(5) Inaudible</scalelabel>
-			</scales>
-		</interface>
-		<audioelement url="0.wav" id="track-3"/>
-		<audioelement url="1.wav" id="track-4"/>
-        <commentquestion id="preference1" type="radio">
-			<statement>Please enter your overall preference</statement>
-			<option name="worst">Very Bad</option>
-			<option name="bad"></option>
-			<option name="OK">OK</option>
-			<option name="Good"></option>
-			<option name="Great">Great</option>
-		</commentquestion>
-		<commentquestion id="character1" type="checkbox">
-			<statement>Please describe the overall character</statement>
-			<option name="funky">Funky</option>
-			<option name="mellow">Mellow</option>
-			<option name="laidback">Laid back</option>
-			<option name="heavy">Heavy</option>
-		</commentquestion>
-	</page>
-</waet>
+    <waet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test-schema.xsd">
+        <setup interface="timeline" projectReturn="save.php">
+            <metric>
+                <metricenable>testTimer</metricenable>
+                <metricenable>elementTimer</metricenable>
+                <metricenable>elementInitialPosition</metricenable>
+                <metricenable>elementTracker</metricenable>
+                <metricenable>elementFlagListenedTo</metricenable>
+                <metricenable>elementFlagMoved</metricenable>
+                <metricenable>elementListenTracker</metricenable>
+            </metric>
+            <interface>
+                <interfaceoption type="check" name="fragmentPlayed" />
+                <interfaceoption type="check" name="scalerange" min="25" max="75" />
+                <interfaceoption type="show" name="volume" />
+                <interfaceoption type="show" name='playhead' />
+                <interfaceoption type="show" name="page-count" />
+                <interfaceoption type="show" name="comments" />
+            </interface>
+        </setup>
+        <page id='test-0' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
+            <title>My Test</title>
+            <interface>
+                <scales>
+                    <scalelabel position="0">(1) Very Annoying</scalelabel>
+                    <scalelabel position="25">(2) Annoying</scalelabel>
+                    <scalelabel position="50">(3) Slightly Annoying</scalelabel>
+                    <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
+                    <scalelabel position="100">(5) Inaudible</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-1" />
+            <audioelement url="1.wav" id="track-2" />
+            <commentquestion id="preference" type="radio">
+                <statement>Please enter your overall preference</statement>
+                <option name="worst">Very Bad</option>
+                <option name="bad"></option>
+                <option name="OK">OK</option>
+                <option name="Good"></option>
+                <option name="Great">Great</option>
+            </commentquestion>
+            <commentquestion id="character" type="checkbox">
+                <statement>Please describe the overall character</statement>
+                <option name="funky">Funky</option>
+                <option name="mellow">Mellow</option>
+                <option name="laidback">Laid back</option>
+                <option name="heavy">Heavy</option>
+            </commentquestion>
+        </page>
+        <page id='test-1' hostURL="media/example/" randomiseOrder='true' repeatCount='4' loop='true' loudness="-23">
+            <title>My Test</title>
+            <interface>
+                <scales>
+                    <scalelabel position="0">(1) Very Annoying</scalelabel>
+                    <scalelabel position="25">(2) Annoying</scalelabel>
+                    <scalelabel position="50">(3) Slightly Annoying</scalelabel>
+                    <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
+                    <scalelabel position="100">(5) Inaudible</scalelabel>
+                </scales>
+            </interface>
+            <audioelement url="0.wav" id="track-3" />
+            <audioelement url="1.wav" id="track-4" />
+            <commentquestion id="preference1" type="radio">
+                <statement>Please enter your overall preference</statement>
+                <option name="worst">Very Bad</option>
+                <option name="bad"></option>
+                <option name="OK">OK</option>
+                <option name="Good"></option>
+                <option name="Great">Great</option>
+            </commentquestion>
+            <commentquestion id="character1" type="checkbox">
+                <statement>Please describe the overall character</statement>
+                <option name="funky">Funky</option>
+                <option name="mellow">Mellow</option>
+                <option name="laidback">Laid back</option>
+                <option name="heavy">Heavy</option>
+            </commentquestion>
+        </page>
+    </waet>
--- a/xml/scaledefinitions.xml	Mon Nov 14 12:11:38 2016 +0000
+++ b/xml/scaledefinitions.xml	Mon Nov 14 14:17:03 2016 +0000
@@ -1,56 +1,56 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<scaledefinitions>
-	<scale name="Likert">
-		<scalelabel position="0">Strongly Disagree</scalelabel>
-		<scalelabel position="25">Disagree</scalelabel>
-		<scalelabel position="50">Neutral</scalelabel>
-		<scalelabel position="75">Agree</scalelabel>
-		<scalelabel position="100">Strongly Agree</scalelabel>
-	</scale>
-	<scale name="ABC">
-		<scalelabel position="100">Imperceptible</scalelabel>
-		<scalelabel position="75">Perceptible but not annoying</scalelabel>
-		<scalelabel position="50">Slightly annoying</scalelabel>
-		<scalelabel position="25">Annoying</scalelabel>
-		<scalelabel position="0">Very annoying</scalelabel>
-	</scale>
-	<scale name="Bipolar">
-		<scalelabel position="0">-50</scalelabel>
-		<scalelabel position="50">0</scalelabel>
-		<scalelabel position="100">50</scalelabel>
-	</scale>
-	<scale name="ACR">
-		<scalelabel position="0">Bad</scalelabel>
-		<scalelabel position="25">Poor</scalelabel>
-		<scalelabel position="50">Fair</scalelabel>
-		<scalelabel position="75">Good</scalelabel>
-		<scalelabel position="100">Excellent</scalelabel>
-	</scale>
-	<scale name="DCR">
-		<scalelabel position="0">(1) Very Annoying</scalelabel>
-		<scalelabel position="25">(2) Annoying</scalelabel>
-		<scalelabel position="50">(3) Slightly Annoying</scalelabel>
-		<scalelabel position="75">(4) Audible but not Annoying</scalelabel>
-		<scalelabel position="100">(5) Inaudible</scalelabel>
-	</scale>
-	<scale name="CCR">
-		<scalelabel position="12">Much Worse</scalelabel>
-		<scalelabel position="25">Worse</scalelabel>
-		<scalelabel position="38">Slightly Worse</scalelabel>
-		<scalelabel position="50">About the same</scalelabel>
-		<scalelabel position="62">Slightly Better</scalelabel>
-		<scalelabel position="75">Better</scalelabel>
-		<scalelabel position="88">Much Better</scalelabel>
-	</scale>
-	<scale name="Hedonic Category Rating Scale">
-		<scalelabel position="10">Dislike Extremely</scalelabel>
-		<scalelabel position="20">Dislike Very Much</scalelabel>
-		<scalelabel position="30">Dislike Moderate</scalelabel>
-		<scalelabel position="40">Dislike Slightly</scalelabel>
-		<scalelabel position="50">Neither Like nor Dislike</scalelabel>
-		<scalelabel position="60">Like Slightly</scalelabel>
-		<scalelabel position="70">Like Moderate</scalelabel>
-		<scalelabel position="80">Like Very Much</scalelabel>
-		<scalelabel position="90">Like Extremely</scalelabel>
-	</scale>
-</scaledefinitions>
+    <scaledefinitions>
+        <scale name="Likert">
+            <scalelabel position="0">Strongly Disagree</scalelabel>
+            <scalelabel position="25">Disagree</scalelabel>
+            <scalelabel position="50">Neutral</scalelabel>
+            <scalelabel position="75">Agree</scalelabel>
+            <scalelabel position="100">Strongly Agree</scalelabel>
+        </scale>
+        <scale name="ABC">
+            <scalelabel position="100">Imperceptible</scalelabel>
+            <scalelabel position="75">Perceptible but not annoying</scalelabel>
+            <scalelabel position="50">Slightly annoying</scalelabel>
+            <scalelabel position="25">Annoying</scalelabel>
+            <scalelabel position="0">Very annoying</scalelabel>
+        </scale>
+        <scale name="Bipolar">
+            <scalelabel position="0">-50</scalelabel>
+            <scalelabel position="50">0</scalelabel>
+            <scalelabel position="100">50</scalelabel>
+        </scale>
+        <scale name="ACR">
+            <scalelabel position="0">Bad</scalelabel>
+            <scalelabel position="25">Poor</scalelabel>
+            <scalelabel position="50">Fair</scalelabel>
+            <scalelabel position="75">Good</scalelabel>
+            <scalelabel position="100">Excellent</scalelabel>
+        </scale>
+        <scale name="DCR">
+            <scalelabel position="0">(1) Very Annoying</scalelabel>
+            <scalelabel position="25">(2) Annoying</scalelabel>
+            <scalelabel position="50">(3) Slightly Annoying</scalelabel>
+            <scalelabel position="75">(4) Audible but not Annoying</scalelabel>
+            <scalelabel position="100">(5) Inaudible</scalelabel>
+        </scale>
+        <scale name="CCR">
+            <scalelabel position="12">Much Worse</scalelabel>
+            <scalelabel position="25">Worse</scalelabel>
+            <scalelabel position="38">Slightly Worse</scalelabel>
+            <scalelabel position="50">About the same</scalelabel>
+            <scalelabel position="62">Slightly Better</scalelabel>
+            <scalelabel position="75">Better</scalelabel>
+            <scalelabel position="88">Much Better</scalelabel>
+        </scale>
+        <scale name="Hedonic Category Rating Scale">
+            <scalelabel position="10">Dislike Extremely</scalelabel>
+            <scalelabel position="20">Dislike Very Much</scalelabel>
+            <scalelabel position="30">Dislike Moderate</scalelabel>
+            <scalelabel position="40">Dislike Slightly</scalelabel>
+            <scalelabel position="50">Neither Like nor Dislike</scalelabel>
+            <scalelabel position="60">Like Slightly</scalelabel>
+            <scalelabel position="70">Like Moderate</scalelabel>
+            <scalelabel position="80">Like Very Much</scalelabel>
+            <scalelabel position="90">Like Extremely</scalelabel>
+        </scale>
+    </scaledefinitions>
--- a/xml/test-schema.xsd	Mon Nov 14 12:11:38 2016 +0000
+++ b/xml/test-schema.xsd	Mon Nov 14 14:17:03 2016 +0000
@@ -26,8 +26,8 @@
                 </xs:restriction>
             </xs:simpleType>
         </xs:attribute>
-        
-        <xs:attribute name="playOne" type="xs:boolean" default="false"/>
+
+        <xs:attribute name="playOne" type="xs:boolean" default="false" />
 
         <!-- define complex elements-->
         <xs:element name="waet">
@@ -254,16 +254,16 @@
                                         <xs:attribute name="check" use="required">
                                             <xs:simpleType>
                                                 <xs:restriction base="xs:string">
-                                                    <xs:enumeration value="equals"/>
-                                                    <xs:enumeration value="lessThan"/>
-                                                    <xs:enumeration value="greaterThan"/>
-                                                    <xs:enumeration value="stringContains"/>
+                                                    <xs:enumeration value="equals" />
+                                                    <xs:enumeration value="lessThan" />
+                                                    <xs:enumeration value="greaterThan" />
+                                                    <xs:enumeration value="stringContains" />
                                                 </xs:restriction>
                                             </xs:simpleType>
                                         </xs:attribute>
-                                        <xs:attribute name="value" type="xs:string" use="optional"/>
-                                        <xs:attribute name="jumpToOnPass" type="xs:string" use="optional"/>
-                                        <xs:attribute name="jumpToOnFail" type="xs:string" use="optional"/>
+                                        <xs:attribute name="value" type="xs:string" use="optional" />
+                                        <xs:attribute name="jumpToOnPass" type="xs:string" use="optional" />
+                                        <xs:attribute name="jumpToOnFail" type="xs:string" use="optional" />
                                     </xs:complexType>
                                 </xs:element>
                             </xs:sequence>
@@ -295,7 +295,7 @@
                                     </xs:restriction>
                                 </xs:simpleType>
                             </xs:attribute>
-                            <xs:attribute name="url" type="xs:string" use="optional"/>
+                            <xs:attribute name="url" type="xs:string" use="optional" />
                         </xs:complexType>
                     </xs:element>
                 </xs:sequence>