| var addSorting = (function () { | 
|     "use strict"; | 
|     var cols, | 
|         currentSort = { | 
|             index: 0, | 
|             desc: false | 
|         }; | 
|   | 
|     // returns the summary table element | 
|     function getTable() { return document.querySelector('.coverage-summary table'); } | 
|     // returns the thead element of the summary table | 
|     function getTableHeader() { return getTable().querySelector('thead tr'); } | 
|     // returns the tbody element of the summary table | 
|     function getTableBody() { return getTable().querySelector('tbody'); } | 
|     // returns the th element for nth column | 
|     function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } | 
|   | 
|     // loads all columns | 
|     function loadColumns() { | 
|         var colNodes = getTableHeader().querySelectorAll('th'), | 
|             colNode, | 
|             cols = [], | 
|             col, | 
|             i; | 
|   | 
|         for (i = 0; i < colNodes.length; i += 1) { | 
|             colNode = colNodes[i]; | 
|             col = { | 
|                 key: colNode.getAttribute('data-col'), | 
|                 sortable: !colNode.getAttribute('data-nosort'), | 
|                 type: colNode.getAttribute('data-type') || 'string' | 
|             }; | 
|             cols.push(col); | 
|             if (col.sortable) { | 
|                 col.defaultDescSort = col.type === 'number'; | 
|                 colNode.innerHTML = colNode.innerHTML + '<span class="sorter"></span>'; | 
|             } | 
|         } | 
|         return cols; | 
|     } | 
|     // attaches a data attribute to every tr element with an object | 
|     // of data values keyed by column name | 
|     function loadRowData(tableRow) { | 
|         var tableCols = tableRow.querySelectorAll('td'), | 
|             colNode, | 
|             col, | 
|             data = {}, | 
|             i, | 
|             val; | 
|         for (i = 0; i < tableCols.length; i += 1) { | 
|             colNode = tableCols[i]; | 
|             col = cols[i]; | 
|             val = colNode.getAttribute('data-value'); | 
|             if (col.type === 'number') { | 
|                 val = Number(val); | 
|             } | 
|             data[col.key] = val; | 
|         } | 
|         return data; | 
|     } | 
|     // loads all row data | 
|     function loadData() { | 
|         var rows = getTableBody().querySelectorAll('tr'), | 
|             i; | 
|   | 
|         for (i = 0; i < rows.length; i += 1) { | 
|             rows[i].data = loadRowData(rows[i]); | 
|         } | 
|     } | 
|     // sorts the table using the data for the ith column | 
|     function sortByIndex(index, desc) { | 
|         var key = cols[index].key, | 
|             sorter = function (a, b) { | 
|                 a = a.data[key]; | 
|                 b = b.data[key]; | 
|                 return a < b ? -1 : a > b ? 1 : 0; | 
|             }, | 
|             finalSorter = sorter, | 
|             tableBody = document.querySelector('.coverage-summary tbody'), | 
|             rowNodes = tableBody.querySelectorAll('tr'), | 
|             rows = [], | 
|             i; | 
|   | 
|         if (desc) { | 
|             finalSorter = function (a, b) { | 
|                 return -1 * sorter(a, b); | 
|             }; | 
|         } | 
|   | 
|         for (i = 0; i < rowNodes.length; i += 1) { | 
|             rows.push(rowNodes[i]); | 
|             tableBody.removeChild(rowNodes[i]); | 
|         } | 
|   | 
|         rows.sort(finalSorter); | 
|   | 
|         for (i = 0; i < rows.length; i += 1) { | 
|             tableBody.appendChild(rows[i]); | 
|         } | 
|     } | 
|     // removes sort indicators for current column being sorted | 
|     function removeSortIndicators() { | 
|         var col = getNthColumn(currentSort.index), | 
|             cls = col.className; | 
|   | 
|         cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); | 
|         col.className = cls; | 
|     } | 
|     // adds sort indicators for current column being sorted | 
|     function addSortIndicators() { | 
|         getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; | 
|     } | 
|     // adds event listeners for all sorter widgets | 
|     function enableUI() { | 
|         var i, | 
|             el, | 
|             ithSorter = function ithSorter(i) { | 
|                 var col = cols[i]; | 
|   | 
|                 return function () { | 
|                     var desc = col.defaultDescSort; | 
|   | 
|                     if (currentSort.index === i) { | 
|                         desc = !currentSort.desc; | 
|                     } | 
|                     sortByIndex(i, desc); | 
|                     removeSortIndicators(); | 
|                     currentSort.index = i; | 
|                     currentSort.desc = desc; | 
|                     addSortIndicators(); | 
|                 }; | 
|             }; | 
|         for (i =0 ; i < cols.length; i += 1) { | 
|             if (cols[i].sortable) { | 
|                 el = getNthColumn(i).querySelector('.sorter'); | 
|                 if (el.addEventListener) { | 
|                     el.addEventListener('click', ithSorter(i)); | 
|                 } else { | 
|                     el.attachEvent('onclick', ithSorter(i)); | 
|                 } | 
|             } | 
|         } | 
|     } | 
|     // adds sorting functionality to the UI | 
|     return function () { | 
|         if (!getTable()) { | 
|             return; | 
|         } | 
|         cols = loadColumns(); | 
|         loadData(cols); | 
|         addSortIndicators(); | 
|         enableUI(); | 
|     }; | 
| })(); | 
|   | 
| window.addEventListener('load', addSorting); |