<html>
<!--
Copyright 2016 the V8 project authors. All rights reserved.  Use of this source
code is governed by a BSD-style license that can be found in the LICENSE file.
-->

<head>
  <meta charset="UTF-8">
  <style>
    body {
      font-family: arial;
    }
    
    table {
      display: table;
      border-spacing: 0px;
    }
    
    tr {
      border-spacing: 0px;
      padding: 10px;
    }
    
    td,
    th {
      padding: 3px 10px 3px 5px;
    }
    
    .inline {
      display: inline-block;
      vertical-align: top;
    }
    
    h2,
    h3 {
      margin-bottom: 0px;
    }
    
    .hidden {
      display: none;
    }
    
    .view {
      display: table;
    }
    
    .column {
      display: table-cell;
      border-right: 1px black dotted;
      min-width: 200px;
    }
    
    .column .header {
      padding: 0 10px 0 10px
    }
    
    #column {
      display: none;
    }
   
    .list {
      width: 100%;
    }
    
    select {
      width: 100%
    }
    
    .list tbody {
      cursor: pointer;
    }
    
    .list tr:nth-child(even) {
      background-color: #EFEFEF;
    }
    
    .list tr:nth-child(even).selected {
      background-color: #DDD;
    }
    
    .list tr.child {
      display: none;
    }
    
    .list tr.child.visible {
      display: table-row;
    }
    
    .list .child .name {
      padding-left: 20px;
    }
    
    .list .parent td {
      border-top: 1px solid #AAA;
    }
    
    .list .total {
      font-weight: bold
    }
    
    .list tr.parent {
      background-color: #FFF;
    }
    
    .list tr.parent.selected {
      background-color: #DDD;
    }
    
    tr.selected {
      background-color: #DDD;
    }
    
    .codeSearch {
      display: block-inline;
      float: right;
      border-radius: 5px;
      background-color: #EEE;
      width: 1em;
      text-align: center;
    }
    
    .list .position {
      text-align: right;
      display: none;
    }
    
    .list div.toggle {
      cursor: pointer;
    }
    
    #column_0 .position {
      display: table-cell;
    }
    
    #column_0 .name {
      display: table-cell;
    }
    
    .list .name {
      display: none;
      white-space: nowrap;
    }
    
    .value {
      text-align: right;
    }
    
    .selectedVersion {
      font-weight: bold;
    }
    
    #baseline {
      width: auto;
    }
    
    .compareSelector {
      padding-bottom: 20px;
    }
    
    .pageDetailTable tbody {
      cursor: pointer
    }
    
    .pageDetailTable tfoot td {
      border-top: 1px grey solid;
    }
    
    #popover {
      position: absolute;
      transform: translateY(-50%) translateX(40px);
      box-shadow: -2px 10px 44px -10px #000;
      border-radius: 5px;
      z-index: 1;
      background-color: #FFF;
      display: none;
      white-space: nowrap;
    }
    
    #popover table {
      position: relative;
      z-index: 1;
      text-align: right;
      margin: 10px;
    }
    #popover td {
      padding: 3px 0px 3px 5px;
      white-space: nowrap;
    }
    
    .popoverArrow {
      background-color: #FFF;
      position: absolute;
      width: 30px;
      height: 30px;
      transform: translateY(-50%)rotate(45deg);
      top: 50%;
      left: -10px;
      z-index: 0;
    }
    
    #popover .name {
      padding: 5px;
      font-weight: bold;
      text-align: center;
    }
    
    #popover table .compare {
      display: none
    }
    
    #popover table.compare .compare {
      display: table-cell;
    }

    #popover .compare .time,
    #popover .compare .version {
      padding-left: 10px;
    }
    .graph,
    .graph .content {
      width: 100%;
    }

    .diff .hideDiff {
      display: none;
    }
    .noDiff .hideNoDiff {
      display: none;
    }
  </style>
  <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
  <script type="text/javascript">
    "use strict"
    google.charts.load('current', {packages: ['corechart']});

    // Did anybody say monkeypatching?
    if (!NodeList.prototype.forEach) {
      NodeList.prototype.forEach = function(func) {
        for (var i = 0; i < this.length; i++) {
          func(this[i]);
        }
      }
    }

    var versions;
    var pages;
    var selectedPage;
    var baselineVersion;
    var selectedEntry;

    function initialize() {
      var original = $("column");
      var view = document.createElement('div');
      view.id = 'view';
      var i = 0;
      versions.forEach((version) =>  {
        if (!version.enabled) return;
        // add column
        var column = original.cloneNode(true);
        column.id = "column_" + i;
        // Fill in all versions
        var select = column.querySelector(".version");
        select.id = "selectVersion_" + i;
        // add all select options
        versions.forEach((version) => {
          if (!version.enabled) return;
          var option = document.createElement("option");
          option.textContent = version.name;
          option.version = version;
          select.appendChild(option);
        });
        // Fill in all page versions
        select = column.querySelector(".pageVersion");
        select.id = "select_" + i;
        // add all pages
        versions.forEach((version) => {
          if (!version.enabled) return;
          var optgroup = document.createElement("optgroup");
          optgroup.label = version.name;
          optgroup.version = version;
          version.forEachPage((page) => {
            var option = document.createElement("option");
            option.textContent = page.name;
            option.page = page;
            optgroup.appendChild(option);
          });
          select.appendChild(optgroup);
        });
        view.appendChild(column);
        i++;
      });
      var oldView = $('view');
      oldView.parentNode.replaceChild(view, oldView);
      
      var select = $('baseline');
      removeAllChildren(select);
      select.appendChild(document.createElement('option'));
      versions.forEach((version) => {
        var option = document.createElement("option");
        option.textContent = version.name;
        option.version = version;
        select.appendChild(option);
      });
      initializeToggleList(versions.versions, $('versionSelector'));
      initializeToggleList(pages.values(), $('pageSelector'));
      initializeToggleContentVisibility();
    }

    function initializeToggleList(items, node) {
      var list = node.querySelector('ul');
      removeAllChildren(list);
      items = Array.from(items);
      items.sort(NameComparator);
      items.forEach((item) => {
        var li = document.createElement('li');
        var checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = item.enabled;
        checkbox.item = item;
        checkbox.addEventListener('click', handleToggleVersionEnable);
        li.appendChild(checkbox);
        li.appendChild(document.createTextNode(item.name));
        list.appendChild(li);
      });
      $('results').querySelectorAll('#results > .hidden').forEach((node) => {
        toggleCssClass(node, 'hidden', false);
      })
    }

    function initializeToggleContentVisibility() {
      var nodes = document.querySelectorAll('.toggleContentVisibility');
      nodes.forEach((node) => {
        var content = node.querySelector('.content');
        var header = node.querySelector('h1,h2,h3');
        if (content === undefined || header === undefined) return;
        if (header.querySelector('input') != undefined) return;
        var checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = content.className.indexOf('hidden') == -1;
        checkbox.contentNode = content;
        checkbox.addEventListener('click', handleToggleContentVisibility);
        header.insertBefore(checkbox, header.childNodes[0]);
      });
    }

    function showPage(firstPage) {
      var changeSelectedEntry = selectedEntry !== undefined 
          && selectedEntry.page === selectedPage;
      selectedPage = firstPage;
      selectedPage.sort();
      showPageInColumn(firstPage, 0);
      // Show the other versions of this page in the following columns.
      var pageVersions = versions.getPageVersions(firstPage);
      var index = 1;
      pageVersions.forEach((page) => {
        if (page !== firstPage) {
          showPageInColumn(page, index);
          index++;
        }
      });
      if (changeSelectedEntry) {
        showEntryDetail(selectedPage.getEntry(selectedEntry));
      } else {
        showImpactList(selectedPage);
      }
    }

    function showPageInColumn(page, columnIndex) {
      page.sort();
      var showDiff = (baselineVersion === undefined && columnIndex !== 0) ||
        (baselineVersion !== undefined && page.version !== baselineVersion);
      var diffStatus = (td, a, b) => {};
      if (showDiff) {
        if (baselineVersion !== undefined) {
          diffStatus = (td, a, b) => {
            if (a == 0) return;
            td.style.color = a < 0 ? '#FF0000' : '#00BB00';
          };
        } else {
          diffStatus = (td, a, b) => {
            if (a == b) return;
            var color;
            var ratio = a / b;
            if (ratio > 1) {
              ratio = Math.min(Math.round((ratio - 1) * 255 * 10), 200);
              color = '#' + ratio.toString(16) + "0000";
            } else {
              ratio = Math.min(Math.round((1 - ratio) * 255 * 10), 200);
              color = '#00' + ratio.toString(16) + "00";
            }
            td.style.color = color;
          }
        }
      }

      var column = $('column_' + columnIndex);
      var select = $('select_' + columnIndex);
      // Find the matching option
      selectOption(select, (i, option) => {
        return option.page == page
      });
      var table = column.querySelector("table");
      var oldTbody = table.querySelector('tbody');
      var tbody = document.createElement('tbody');
      var referencePage = selectedPage;
      page.forEachSorted(selectedPage, (parentEntry, entry, referenceEntry) => {
        // Filter out entries that do not exist in the first column for the default
        // view.
        if (baselineVersion === undefined && referenceEntry &&
          referenceEntry.time == 0) {
          return;
        }
        var tr = document.createElement('tr');
        tbody.appendChild(tr);
        tr.entry = entry;
        tr.parentEntry = parentEntry;
        tr.className = parentEntry === undefined ? 'parent' : 'child';
        // Don't show entries that do not exist on the current page or if we
        // compare against the current page
        if (entry !== undefined && page.version !== baselineVersion) {
          // If we show a diff, use the baselineVersion as the referenceEntry
          if (baselineVersion !== undefined) {
            var baselineEntry = baselineVersion.getEntry(entry);
            if (baselineEntry !== undefined) referenceEntry = baselineEntry
          }
          if (!parentEntry) {
            var node = td(tr, '<div class="toggle">►</div>', 'position');
            node.firstChild.addEventListener('click', handleToggleGroup);
          } else {
            td(tr, entry.position == 0 ? '' : entry.position, 'position');
          }
          addCodeSearchButton(entry,
              td(tr, entry.name, 'name ' + entry.cssClass()));
          
          diffStatus(
            td(tr, ms(entry.time), 'value time'),
            entry.time, referenceEntry.time);
          diffStatus(
            td(tr, percent(entry.timePercent), 'value time'),
            entry.time, referenceEntry.time);
          diffStatus(
            td(tr, count(entry.count), 'value count'),
            entry.count, referenceEntry.count);
        } else if (baselineVersion !== undefined && referenceEntry 
            && page.version !== baselineVersion) {
          // Show comparison of entry that does not exist on the current page.
          tr.entry = new Entry(0, referenceEntry.name);
          tr.entry.page = page;
          td(tr, '-', 'position');
          td(tr, referenceEntry.name, 'name');
          diffStatus(
            td(tr, ms(-referenceEntry.time), 'value time'),
            -referenceEntry.time, 0);
          diffStatus(
            td(tr, percent(-referenceEntry.timePercent), 'value time'),
            -referenceEntry.timePercent, 0);
          diffStatus(
            td(tr, count(-referenceEntry.count), 'value count'),
            -referenceEntry.count, 0);
        } else {
          // Display empty entry / baseline entry
          var showBaselineEntry = entry !== undefined;
          if (showBaselineEntry) {
            if (!parentEntry) {
              var node = td(tr, '<div class="toggle">►</div>', 'position');
              node.firstChild.addEventListener('click', handleToggleGroup);
            } else {
              td(tr, entry.position == 0 ? '' : entry.position, 'position');
            }
            td(tr, entry.name, 'name');
            td(tr, ms(entry.time, false), 'value time');
            td(tr, percent(entry.timePercent, false), 'value time');
            td(tr, count(entry.count, false), 'value count');
          } else {
            td(tr, '-', 'position');
            td(tr, '-', 'name');
            td(tr, '-', 'value time');
            td(tr, '-', 'value time');
            td(tr, '-', 'value count');
          }
        }
      });
      table.replaceChild(tbody, oldTbody);
      var versionSelect = column.querySelector('select.version');
      selectOption(versionSelect, (index, option) => {
        return option.version == page.version
      });
    }

    function selectEntry(entry, updateSelectedPage) {
      if (updateSelectedPage) {
        entry = selectedPage.version.getEntry(entry);
      }
      var rowIndex = 0;
      var needsPageSwitch = updateSelectedPage && entry.page != selectedPage;
      // If clicked in the detail row change the first column to that page.
      if (needsPageSwitch) showPage(entry.page);
      var childNodes = $('column_0').querySelector('.list tbody').childNodes;
      for (var i = 0; i < childNodes.length; i++) {
        if (childNodes[i].entry.name == entry.name) {
          rowIndex = i;
          break;
        }
      }
      var firstEntry = childNodes[rowIndex].entry;
      if (rowIndex) {
        if (firstEntry.parent) showGroup(firstEntry.parent);
      }
      // Deselect all
      $('view').querySelectorAll('.list tbody tr').forEach((tr) => {
        toggleCssClass(tr, 'selected', false);
      });
      // Select the entry row
      $('view').querySelectorAll("tbody").forEach((body) => {
        var row = body.childNodes[rowIndex];
        if (!row) return;
        toggleCssClass(row, 'selected', row.entry && row.entry.name ==
          firstEntry.name);
      });
      if (updateSelectedPage) {
        entry = selectedEntry.page.version.getEntry(entry);
      }
      selectedEntry = entry;
      showEntryDetail(entry);
    }

    function showEntryDetail(entry) {
      showVersionDetails(entry);
      showPageDetails(entry);
      showImpactList(entry.page);
      showGraphs(entry.page);
    }
    
    function showVersionDetails(entry) {
      var table, tbody, entries;
      table = $('detailView').querySelector('.versionDetailTable');
      tbody = document.createElement('tbody');
      if (entry !== undefined) {
        $('detailView').querySelector('.versionDetail h3 span').innerHTML =
          entry.name + ' in ' + entry.page.name;
        entries = versions.getPageVersions(entry.page).map(
          (page) => {
            return page.get(entry.name)
          });
        entries.sort((a, b) => {
          return a.time - b.time
        });
        entries.forEach((pageEntry) => {
          if (pageEntry === undefined) return;
          var tr = document.createElement('tr');
          if (pageEntry == entry) tr.className += 'selected';
          tr.entry = pageEntry;
          var isBaselineEntry = pageEntry.page.version == baselineVersion;
          td(tr, pageEntry.page.version.name, 'version');
          td(tr, ms(pageEntry.time, !isBaselineEntry), 'value time');
          td(tr, percent(pageEntry.timePercent, !isBaselineEntry), 'value time');
          td(tr, count(pageEntry.count, !isBaselineEntry), 'value count');
          tbody.appendChild(tr);
        });
      }
      table.replaceChild(tbody, table.querySelector('tbody'));
    }

    function showPageDetails(entry) {
      var table, tbody, entries;
      table = $('detailView').querySelector('.pageDetailTable');
      tbody = document.createElement('tbody');
      if (entry === undefined) {
        table.replaceChild(tbody, table.querySelector('tbody'));
        return;
      }
      var version = entry.page.version;
      var showDiff = version !== baselineVersion;
      $('detailView').querySelector('.pageDetail h3 span').innerHTML =
        version.name;
      entries = version.pages.map((page) => {
          if (!page.enabled) return;
          return page.get(entry.name)
        });
      entries.sort((a, b) => {
        var cmp = b.timePercent - a.timePercent;
        if (cmp.toFixed(1) == 0) return b.time - a.time;
        return cmp
      });
      entries.forEach((pageEntry) => {
        if (pageEntry === undefined) return;
        var tr = document.createElement('tr');
        if (pageEntry === entry) tr.className += 'selected';
        tr.entry = pageEntry;
        td(tr, pageEntry.page.name, 'name');
        td(tr, ms(pageEntry.time, showDiff), 'value time');
        td(tr, percent(pageEntry.timePercent, showDiff), 'value time');
        td(tr, percent(pageEntry.timePercentPerEntry, showDiff),
            'value time hideNoDiff');
        td(tr, count(pageEntry.count, showDiff), 'value count');
        tbody.appendChild(tr);
      });
      // show the total for all pages
      var tds = table.querySelectorAll('tfoot td');
      tds[1].innerHTML = ms(entry.getTimeImpact(), showDiff);
      // Only show the percentage total if we are in diff mode:
      tds[2].innerHTML = percent(entry.getTimePercentImpact(), showDiff);
      tds[3].innerHTML = '';
      tds[4].innerHTML = count(entry.getCountImpact(), showDiff);
      table.replaceChild(tbody, table.querySelector('tbody'));
    }

    function showImpactList(page) {
      var impactView = $('detailView').querySelector('.impactView');
      impactView.querySelector('h3 span').innerHTML = page.version.name;

      var table = impactView.querySelector('table');
      var tbody = document.createElement('tbody');
      var version = page.version;
      var entries = version.allEntries();
      if (selectedEntry !== undefined && selectedEntry.isGroup) {
        impactView.querySelector('h3 span').innerHTML += " " + selectedEntry.name;
        entries = entries.filter((entry) => {
          return entry.name == selectedEntry.name ||
            (entry.parent && entry.parent.name == selectedEntry.name)
        });
      }
      var isCompareView = baselineVersion !== undefined;
      entries = entries.filter((entry) => {
        if (isCompareView) {
          var impact = entry.getTimeImpact();
          return impact < -1 || 1 < impact
        }
        return entry.getTimePercentImpact() > 0.1;
      });
      entries.sort((a, b) => {
        var cmp = b.getTimePercentImpact() - a.getTimePercentImpact(); 
        if (isCompareView || cmp.toFixed(1) == 0) {
          return b.getTimeImpact() - a.getTimeImpact();
        }
        return cmp
      });
      entries.forEach((entry) => {
        var tr = document.createElement('tr');
        tr.entry = entry;
        td(tr, entry.name, 'name');
        td(tr, ms(entry.getTimeImpact()), 'value time');
        var percentImpact = entry.getTimePercentImpact();
        td(tr, percentImpact > 1000 ? '-' : percent(percentImpact), 'value time');
        var topPages = entry.getPagesByPercentImpact().slice(0, 3)
          .map((each) => {
            return each.name + ' (' + percent(each.getEntry(entry).timePercent) +
              ')'
          });
        td(tr, topPages.join(', '), 'name');
        tbody.appendChild(tr);
      });
      table.replaceChild(tbody, table.querySelector('tbody'));
    }
    
    function showGraphs(page) {
      var groups = page.groups.slice(); 
      // Sort groups by the biggest impact
      groups.sort((a, b) => {
        return b.getTimeImpact() - a.getTimeImpact();
      });
      if (selectedGroup == undefined) {
        selectedGroup = groups[0];
      } else {
        groups = groups.filter(each => each.name != selectedGroup.name);
        groups.unshift(selectedGroup);
      }
      showPageGraph(groups, page);
      showVersionGraph(groups, page);
      showPageVersionGraph(groups, page);
    }
    
    function getGraphDataTable(groups) {
      var dataTable = new google.visualization.DataTable();
      dataTable.addColumn('string', 'Name');
      groups.forEach(group => {
        var column = dataTable.addColumn('number', group.name.substring(6));
        dataTable.setColumnProperty(column, 'group', group);
      });
      return dataTable;
    }

    var selectedGroup;
    function showPageGraph(groups, page) {
      var isDiffView = baselineVersion !== undefined;
      var dataTable = getGraphDataTable(groups);
      // Calculate the average row
      var row = ['Average'];
      groups.forEach((group) => {
        if (isDiffView) {
          row.push(group.isTotal ? 0 : group.getAverageTimeImpact());
        } else {
          row.push(group.isTotal ? 0 : group.getTimeImpact());
        }
      });
      dataTable.addRow(row);
      // Sort the pages by the selected group.
      var pages = page.version.pages.filter(page => page.enabled);
      function sumDiff(page) {
        var sum = 0;
        groups.forEach(group => {
          var value = group.getTimePercentImpact() -
            page.getEntry(group).timePercent;
          sum += value * value;
        });
        return sum;
      }
      if (isDiffView) {
        pages.sort((a, b) => {
          return b.getEntry(selectedGroup).time-
            a.getEntry(selectedGroup).time; 
        });
      } else {
        pages.sort((a, b) => {
          return b.getEntry(selectedGroup).timePercent -
            a.getEntry(selectedGroup).timePercent; 
        });
      }
      // Sort by sum of squared distance to the average.
      // pages.sort((a, b) => {
      //   return a.distanceFromTotalPercent() - b.distanceFromTotalPercent(); 
      // });
      // Calculate the entries for the pages
      pages.forEach((page) => { 
        row = [page.name];
        groups.forEach((group) => {
          row.push(group.isTotal ? 0 : page.getEntry(group).time);
        });
        var rowIndex = dataTable.addRow(row);
        dataTable.setRowProperty(rowIndex, 'page', page);
      });
      renderGraph('Pages for ' + page.version.name, groups, dataTable,
          'pageGraph', isDiffView ? true : 'percent');
    }

    function showVersionGraph(groups, page) {
      var dataTable = getGraphDataTable(groups);
      var row;
      var vs = versions.versions.filter(version => version.enabled);
      vs.sort((a, b) => {
        return b.getEntry(selectedGroup).getTimeImpact() -
          a.getEntry(selectedGroup).getTimeImpact(); 
      });
      // Calculate the entries for the versions 
      vs.forEach((version) => { 
        row = [version.name];
        groups.forEach((group) => {
          row.push(group.isTotal ? 0 : version.getEntry(group).getTimeImpact());
        });
        var rowIndex = dataTable.addRow(row);
        dataTable.setRowProperty(rowIndex, 'page', page);
      });
      renderGraph('Versions Total Time over all Pages', groups, dataTable,
          'versionGraph', true);
    }

    function showPageVersionGraph(groups, page) {
      var dataTable = getGraphDataTable(groups);
      var row;
      var vs = versions.getPageVersions(page);
      vs.sort((a, b) => {
        return b.getEntry(selectedGroup).time - a.getEntry(selectedGroup).time; 
      });
      // Calculate the entries for the versions 
      vs.forEach((page) => { 
        row = [page.version.name];
        groups.forEach((group) => {
          row.push(group.isTotal ? 0 : page.getEntry(group).time);
        });
        var rowIndex = dataTable.addRow(row);
        dataTable.setRowProperty(rowIndex, 'page', page);
      });
      renderGraph('Versions for ' + page.name, groups, dataTable,
          'pageVersionGraph', true);
    }

    function renderGraph(title, groups, dataTable, id, isStacked) {
      var isDiffView = baselineVersion !== undefined;
      var formatter = new google.visualization.NumberFormat({
        suffix: (isDiffView ? 'msΔ' : 'ms'), 
        negativeColor: 'red', 
        groupingSymbol: "'"
      });
      for (var i = 1; i < dataTable.getNumberOfColumns(); i++) {
        formatter.format(dataTable, i);
      }
      var height = 85 + 28 * dataTable.getNumberOfRows();
      var options = {
        isStacked: isStacked,
        height: height,
        hAxis: {
          minValue: 0,
        },
        animation:{
          duration: 500,
          easing: 'out',
        },
        vAxis: {
        },
        explorer: {
          actions: ['dragToZoom', 'rightClickToReset'],
          maxZoomIn: 0.01
        },
        legend: {position:'top', textStyle:{fontSize: '16px'}},
        chartArea: {left:200, top:50, width:'98%', height:'80%'},
        colors: groups.map(each => each.color)
      };
      var parentNode = $(id);
      parentNode.querySelector('h2>span, h3>span').innerHTML = title;
      var graphNode = parentNode.querySelector('.content');

      var chart = graphNode.chart;
      if (chart === undefined) {
        chart = graphNode.chart = new google.visualization.BarChart(graphNode);
      } else {
        google.visualization.events.removeAllListeners(chart);
      }
      google.visualization.events.addListener(chart, 'select', selectHandler);
      function getChartEntry(selection) {
        if (!selection) return undefined;
        var column = selection.column;
        if (column == undefined) return undefined;
        var selectedGroup = dataTable.getColumnProperty(column, 'group');
        var row = selection.row;
        if (row == null) return selectedGroup;
        var page = dataTable.getRowProperty(row, 'page');
        if (!page) return selectedGroup;
        return page.getEntry(selectedGroup);
      }
      function selectHandler() {
        selectedGroup = getChartEntry(chart.getSelection()[0])
        if (!selectedGroup) return;
        selectEntry(selectedGroup, true);
      }

      // Make our global tooltips work
      google.visualization.events.addListener(chart, 'onmouseover', mouseOverHandler);
      function mouseOverHandler(selection) {
        graphNode.entry = getChartEntry(selection);
      }
      chart.draw(dataTable, options);
    }

    function showGroup(entry) {
      toggleGroup(entry, true);
    }

    function toggleGroup(group, show) {
      $('view').querySelectorAll(".child").forEach((tr) => {
        var entry = tr.parentEntry;
        if (!entry) return;
        if (entry.name !== group.name) return;
        toggleCssClass(tr, 'visible', show);
      });
    }

    function showPopover(entry) {
      var popover = $('popover');
      popover.querySelector('td.name').innerHTML = entry.name;
      popover.querySelector('td.page').innerHTML = entry.page.name;
      setPopoverDetail(popover, entry, '');
      popover.querySelector('table').className = "";
      if (baselineVersion !== undefined) {
        entry = baselineVersion.getEntry(entry);
        setPopoverDetail(popover, entry, '.compare');
        popover.querySelector('table').className = "compare";
      }
    }

    function setPopoverDetail(popover, entry, prefix) {
      var node = (name) => popover.querySelector(prefix + name);
      if (entry == undefined) {
        node('.version').innerHTML = baselineVersion.name;
        node('.time').innerHTML = '-';
        node('.timeVariance').innerHTML = '-';
        node('.percent').innerHTML = '-';
        node('.percentPerEntry').innerHTML = '-';
        node('.percentVariance').innerHTML  = '-';
        node('.count').innerHTML =  '-';
        node('.countVariance').innerHTML = '-';
        node('.timeImpact').innerHTML = '-';
        node('.timePercentImpact').innerHTML = '-';
      } else {
        node('.version').innerHTML = entry.page.version.name;
        node('.time').innerHTML = ms(entry._time, false);
        node('.timeVariance').innerHTML
            = percent(entry.timeVariancePercent, false);
        node('.percent').innerHTML = percent(entry.timePercent, false);
        node('.percentPerEntry').innerHTML
            = percent(entry.timePercentPerEntry, false);
        node('.percentVariance').innerHTML 
            = percent(entry.timePercentVariancePercent, false);
        node('.count').innerHTML = count(entry._count, false);
        node('.countVariance').innerHTML
            = percent(entry.timeVariancePercent, false);
        node('.timeImpact').innerHTML
            = ms(entry.getTimeImpact(false), false);
        node('.timePercentImpact').innerHTML
            = percent(entry.getTimeImpactVariancePercent(false), false);
      }
    }
  </script>
  <script type="text/javascript">
  "use strict"
    // =========================================================================
    // Helpers
    function $(id) {
      return document.getElementById(id)
    }

    function removeAllChildren(node) {
      while (node.firstChild) {
        node.removeChild(node.firstChild);
      }
    }

    function selectOption(select, match) {
      var options = select.options;
      for (var i = 0; i < options.length; i++) {
        if (match(i, options[i])) {
          select.selectedIndex = i;
          return;
        }
      }
    }

    function addCodeSearchButton(entry, node) {
      if (entry.isGroup) return;
      var button = document.createElement("div");
      button.innerHTML = '?'
      button.className = "codeSearch"
      button.addEventListener('click', handleCodeSearch);
      node.appendChild(button);
      return node;
    }

    function td(tr, content, className) {
      var td = document.createElement("td");
      td.innerHTML = content;
      td.className = className
      tr.appendChild(td);
      return td
    }

    function nodeIndex(node) {
      var children = node.parentNode.childNodes,
        i = 0;
      for (; i < children.length; i++) {
        if (children[i] == node) {
          return i;
        }
      }
      return -1;
    }

    function toggleCssClass(node, cssClass, toggleState) {
      var index = -1;
      var classes;
      if (node.className != undefined) {
        classes = node.className.split(' ');
        index = classes.indexOf(cssClass);
      }
      if (index == -1) {
        if (toggleState === false) return;
        node.className += ' ' + cssClass;
        return;
      }
      if (toggleState === true) return;
      classes.splice(index, 1);
      node.className = classes.join(' ');
    }

    function NameComparator(a, b) {
      if (a.name > b.name) return 1;
      if (a.name < b.name) return -1;
      return 0
    }

    function diffSign(value, digits, unit, showDiff) {
      if (showDiff === false || baselineVersion == undefined) {
        if (value === undefined) return '';
        return value.toFixed(digits) + unit;
      }
      return (value >= 0 ? '+' : '') + value.toFixed(digits) + unit + 'Δ';
    }

    function ms(value, showDiff) {
      return diffSign(value, 1, 'ms', showDiff);
    }

    function count(value, showDiff) {
      return diffSign(value, 0, '#', showDiff);
    }

    function percent(value, showDiff) {
      return diffSign(value, 1, '%', showDiff);
    }

  </script>
  <script type="text/javascript">
  "use strict"
    // =========================================================================
    // EventHandlers
    function handleBodyLoad() {
      $('uploadInput').focus(); 
    }

    function handleLoadFile() {
      var files = document.getElementById("uploadInput").files;
      var file = files[0];
      var reader = new FileReader();

      reader.onload = function(evt) {
        pages = new Pages();
        versions = Versions.fromJSON(JSON.parse(this.result));
        initialize()
        showPage(versions.versions[0].pages[0]);
      }
      reader.readAsText(file);
    }

    function handleToggleGroup(event) {
      var group = event.target.parentNode.parentNode.entry;
      toggleGroup(selectedPage.get(group.name));
    }

    function handleSelectPage(select, event) {
      var option = select.options[select.selectedIndex];
      if (select.id == "select_0") {
        showPage(option.page);
      } else {
        var columnIndex = select.id.split('_')[1];
        showPageInColumn(option.page, columnIndex);
      }
    }

    function handleSelectVersion(select, event) {
      var option = select.options[select.selectedIndex];
      var version = option.version;
      if (select.id == "selectVersion_0") {
        var page = version.get(selectedPage.name);
        showPage(page);
      } else {
        var columnIndex = select.id.split('_')[1];
        var pageSelect = $('select_' + columnIndex);
        var page = pageSelect.options[pageSelect.selectedIndex].page;
        page = version.get(page.name);
        showPageInColumn(page, columnIndex);
      }
    }

    function handleSelectDetailRow(table, event) {
      if (event.target.tagName != 'TD') return;
      var tr = event.target.parentNode;
      if (tr.tagName != 'TR') return;
      if (tr.entry === undefined) return;
      selectEntry(tr.entry, true);
    }

    function handleSelectRow(table, event, fromDetail) {
      if (event.target.tagName != 'TD') return;
      var tr = event.target.parentNode;
      if (tr.tagName != 'TR') return;
      if (tr.entry === undefined) return;
      selectEntry(tr.entry, false);
    }

    function handleSelectBaseline(select, event) {
      var option = select.options[select.selectedIndex];
      baselineVersion = option.version;
      var showingDiff = baselineVersion !== undefined;
      var body = $('body');
      toggleCssClass(body, 'diff', showingDiff);
      toggleCssClass(body, 'noDiff', !showingDiff);
      showPage(selectedPage);
      if (selectedEntry === undefined) return;
      selectEntry(selectedEntry, true);
    }

    function findEntry(event) {
      var target = event.target;
      while (target.entry === undefined) {
        target = target.parentNode;
        if (!target) return undefined;
      }
      return target.entry;
    }

    function handleUpdatePopover(event) {
      var popover = $('popover');
      popover.style.left = event.pageX + 'px';
      popover.style.top = event.pageY + 'px';
      popover.style.display = 'none';
      popover.style.display = event.shiftKey ? 'block' : 'none';
      var entry = findEntry(event);
      if (entry === undefined) return;
      showPopover(entry);
    }

    function handleToggleVersionEnable(event) {
      var item = this.item ;
      if (item  === undefined) return;
      item .enabled = this.checked;
      initialize();
      var page = selectedPage;
      if (page === undefined || !page.version.enabled) {
        page = versions.getEnabledPage(page.name);
      }
      showPage(page);
    }

    function handleToggleContentVisibility(event) {
      var content = event.target.contentNode;
      toggleCssClass(content, 'hidden');
    }

    function handleCodeSearch(event) {
      var entry = findEntry(event);
      if (entry === undefined) return;
      var url = "https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=";
      name = entry.name;
      if (name.startsWith("API_")) {
        name = name.substring(4);
      }
      url += encodeURIComponent(name) + "+file:src/v8/src";
      window.open(url,'_blank');
    }
  </script>
  <script type="text/javascript">
  "use strict"
    // =========================================================================
    class Versions {
      constructor() {
        this.versions = [];
      }
      add(version) {
        this.versions.push(version)
      }
      getPageVersions(page) {
        var result = [];
        this.versions.forEach((version) => {
          if (!version.enabled) return;
          var versionPage = version.get(page.name);
          if (versionPage  !== undefined) result.push(versionPage);
        });
        return result;
      }
      get length() {
        return this.versions.length
      }
      get(index) {
        return this.versions[index]
      };
      forEach(f) {
        this.versions.forEach(f);
      }
      sort() {
        this.versions.sort(NameComparator);
      }
      getEnabledPage(name) {
        for (var i = 0; i < this.versions.length; i++) {
          var version = this.versions[i];
          if (!version.enabled) continue;
          var page = version.get(name);
          if (page !== undefined) return page;
        }
      }
    }
    Versions.fromJSON = function(json) {
      var versions = new Versions();
      for (var version in json) {
        versions.add(Version.fromJSON(version, json[version]));
      }
      versions.sort();
      return versions;
    }

    class Version {
      constructor(name) {
        this.name = name;
        this.enabled = true;
        this.pages = [];
      }
      add(page) {
        this.pages.push(page);
      }
      indexOf(name) {
        for (var i = 0; i < this.pages.length; i++) {
          if (this.pages[i].name == name) return i;
        }
        return -1;
      }
      get(name) {
        var index = this.indexOf(name);
        if (0 <= index) return this.pages[index];
        return undefined
      }
      get length() {
        return this.versions.length
      }
      getEntry(entry) {
        if (entry === undefined) return undefined;
        var page = this.get(entry.page.name);
        if (page === undefined) return undefined;
        return page.get(entry.name);
      }
      forEachEntry(fun) {
        this.forEachPage((page) => {
          page.forEach(fun);
        });
      }
      forEachPage(fun) {
        this.pages.forEach((page) => {
          if (!page.enabled) return;
          fun(page);
        })
      }
      allEntries() {
        var map = new Map();
        this.forEachEntry((group, entry) => {
          if (!map.has(entry.name)) map.set(entry.name, entry);
        });
        return Array.from(map.values());
      }
      getTotalValue(name, property) {
        if (name === undefined) name = this.pages[0].total.name;
        var sum = 0;
        this.forEachPage((page) => {
          var entry = page.get(name);
          if (entry !== undefined) sum += entry[property];
        });
        return sum;
      }
      getTotalTime(name, showDiff) {
        return this.getTotalValue(name, showDiff === false ? '_time' : 'time');
      }
      getTotalTimePercent(name, showDiff) {
        if (baselineVersion === undefined || showDiff === false) {
          // Return the overall average percent of the given entry name.
          return this.getTotalValue(name, 'time') /
            this.getTotalTime('Group-Total') * 100;
        }
        // Otherwise return the difference to the sum of the baseline version.
        var baselineValue = baselineVersion.getTotalTime(name, false);
        var total = this.getTotalValue(name, '_time');
        return (total / baselineValue - 1)  * 100;
      }
      getTotalTimeVariance(name, showDiff) {
        // Calculate the overall error for a given entry name
        var sum = 0;
        this.forEachPage((page) => {
          var entry = page.get(name);
          if (entry === undefined) return;
          sum += entry.timeVariance * entry.timeVariance;
        });
        return Math.sqrt(sum);
      }
      getTotalTimeVariancePercent(name, showDiff) {
        return this.getTotalTimeVariance(name, showDiff) / 
          this.getTotalTime(name, showDiff) * 100;
      }
      getTotalCount(name, showDiff) {
        return this.getTotalValue(name, showDiff === false ? '_count' : 'count');
      }
      getAverageTimeImpact(name, showDiff) {
        return this.getTotalTime(name, showDiff) / this.pages.length;
      }
      getPagesByPercentImpact(name) {
        var sortedPages =
          this.pages.filter((each) => {
            return each.get(name) !== undefined
          });
        sortedPages.sort((a, b) => {
          return b.get(name).timePercent - a.get(name).timePercent;
        });
        return sortedPages;
      }
      sort() {
        this.pages.sort(NameComparator)
      }
    }
    Version.fromJSON = function(name, data) {
      var version = new Version(name);
      for (var pageName in data) {
        version.add(PageVersion.fromJSON(version, pageName, data[pageName]));
      }
      version.sort();
      return version;
    }
    
    class Pages extends Map {
      get(name) {
        if (name.indexOf('www.') == 0) {
          name = name.substring(4);
        }
        if (!this.has(name)) {
          this.set(name, new Page(name));
        }
        return super.get(name);
      }
    }

    class Page {
      constructor(name) {
        this.name = name;
        this.enabled = true;
        this.versions = [];
      }
      add(page) {
        this.versions.push(page);
      }
    }

    class PageVersion {
      constructor(version, page) {
        this.page = page;
        this.page.add(this);
        this.total = new GroupedEntry('Total', /.*Total.*/, '#BBB');
        this.total.isTotal = true;
        this.unclassified = new UnclassifiedEntry(this, "#000")
        this.groups = [
          this.total,
          new GroupedEntry('IC', /.*IC.*/, "#3366CC"),
          new GroupedEntry('Optimize',
            /StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/, "#DC3912"),
          new GroupedEntry('Compile', /.*Compile.*/, "#FFAA00"),
          new GroupedEntry('Parse', /.*Parse.*/, "#FF6600"),
          new GroupedEntry('Callback', /.*Callback$/, "#109618"),
          new GroupedEntry('API', /.*API.*/, "#990099"),
          new GroupedEntry('GC', /GC|AllocateInTargetSpace/, "#0099C6"),
          new GroupedEntry('JavaScript', /JS_Execution/, "#DD4477"),
          new GroupedEntry('Runtime', /.*/, "#88BB00"),
          this.unclassified
        ];
        this.entryDict = new Map();
        this.groups.forEach((entry) => {
          entry.page = this;
          this.entryDict.set(entry.name, entry);
        });
        this.version = version;
      }
      add(entry) {
        entry.page = this;
        this.entryDict.set(entry.name, entry);
        var added = false;
        this.groups.forEach((group) => {
          if (!added) added = group.add(entry);
        });
        if (added) return;
        this.unclassified.push(entry);
      }
      get(name) {
        return this.entryDict.get(name)
      }
      getEntry(entry) {
        if (entry === undefined) return undefined;
        return this.get(entry.name);
      }
      get length() {
        return this.versions.length
      }
      get name() { return this.page.name }
      get enabled() { return this.page.enabled }
      forEachSorted(referencePage, func) {
        // Iterate over all the entries in the order they appear on the
        // reference page.
        referencePage.forEach((parent, referenceEntry) => {
          var entry;
          if (parent) parent = this.entryDict.get(parent.name);
          if (referenceEntry) entry = this.entryDict.get(referenceEntry.name);
          func(parent, entry, referenceEntry);
        });
      }
      forEach(fun) {
        this.forEachGroup((group) => {
          fun(undefined, group);
          group.forEach((entry) => {
            fun(group, entry)
          });
        });
      }
      forEachGroup(fun) {
        this.groups.forEach(fun)
      }
      sort() {
        this.groups.sort((a, b) => {
          return b.time - a.time;
        });
        this.groups.forEach((group) => {
          group.sort()
        });
      }
      distanceFromTotalPercent() {
        var sum = 0;
        this.groups.forEach(group => {
          if (group == this.total) return;
          var value = group.getTimePercentImpact() - 
              this.getEntry(group).timePercent;
          sum += value * value;
        });
        return sum;
      }
    }
    PageVersion.fromJSON = function(version, name, data) {
      var page = new PageVersion(version, pages.get(name));
      for (var i = 0; i < data.length; i++) {
        page.add(Entry.fromJSON(i, data[data.length - i - 1]));
      }
      page.sort();
      return page
    }


    class Entry {
      constructor(position, name, time, timeVariance, timeVariancePercent,
        count,
        countVariance, countVariancePercent) {
        this.position = position;
        this.name = name;
        this._time = time;
        this._timeVariance = timeVariance;
        this._timeVariancePercent = timeVariancePercent;
        this._count = count;
        this.countVariance = countVariance;
        this.countVariancePercent = countVariancePercent;
        this.page = undefined;
        this.parent = undefined;
        this.isTotal = false;
      }
      getCompareWithBaseline(value, property) {
        if (baselineVersion == undefined) return value;
        var baselineEntry = baselineVersion.getEntry(this);
        if (!baselineEntry) return value;
        if (baselineVersion === this.page.version) return value;
        return value - baselineEntry[property];
      }
      cssClass() {
        return ''
      }
      get time() {
        return this.getCompareWithBaseline(this._time, '_time');
      }
      get count() {
        return this.getCompareWithBaseline(this._count, '_count');
      }
      get timePercent() {
        var value = this._time / this.page.total._time * 100;
        if (baselineVersion == undefined) return value;
        var baselineEntry = baselineVersion.getEntry(this);
        if (!baselineEntry) return value;
        if (baselineVersion === this.page.version) return value;
        return (this._time - baselineEntry._time) / this.page.total._time *
          100;
      }
      get timePercentPerEntry() {
        var value = this._time / this.page.total._time * 100;
        if (baselineVersion == undefined) return value;
        var baselineEntry = baselineVersion.getEntry(this);
        if (!baselineEntry) return value;
        if (baselineVersion === this.page.version) return value;
        return (this._time / baselineEntry._time - 1) * 100;
      }
      get timePercentVariancePercent() {
        // Get the absolute values for the percentages
        return this.timeVariance / this.page.total._time * 100;
      }
      getTimeImpact(showDiff) {
        return this.page.version.getTotalTime(this.name, showDiff);
      }
      getTimeImpactVariancePercent(showDiff) {
        return this.page.version.getTotalTimeVariancePercent(this.name, showDiff);
      }
      getTimePercentImpact(showDiff) {
        return this.page.version.getTotalTimePercent(this.name, showDiff);
      }
      getCountImpact(showDiff) {
        return this.page.version.getTotalCount(this.name, showDiff);
      }
      getAverageTimeImpact(showDiff) {
        return this.page.version.getAverageTimeImpact(this.name, showDiff);
      }
      getPagesByPercentImpact() {
        return this.page.version.getPagesByPercentImpact(this.name);
      }
      get isGroup() {
        return false
      }
      get timeVariance() {
        return this._timeVariance
      }
      get timeVariancePercent() {
        return this._timeVariancePercent
      }
    }
    Entry.fromJSON = function(position, data) {
      return new Entry(position, ...data);
    }


    class GroupedEntry extends Entry {
      constructor(name, regexp, color) {
        super(0, 'Group-' + name, 0, 0, 0, 0, 0, 0);
        this.regexp = regexp;
        this.color = color;
        this.entries = [];
      }
      add(entry) {
        if (!entry.name.match(this.regexp)) return false;
        this._time += entry.time;
        this._count += entry.count;
        // TODO: sum up variance
        this.entries.push(entry);
        entry.parent = this;
        return true;
      }
      forEach(fun) {
        if (baselineVersion === undefined) {
          this.entries.forEach(fun);
          return;
        }
        // If we have a baslineVersion to compare against show also all entries
        // from the other group.
        var tmpEntries = baselineVersion.getEntry(this)
          .entries.filter((entry) => {
            return this.page.get(entry.name) == undefined
          });

        // The compared entries are sorted by absolute impact.
        tmpEntries = tmpEntries.map((entry) => {
          var tmpEntry = new Entry(0, entry.name, 0, 0, 0, 0, 0, 0);
          tmpEntry.page = this.page;
          return tmpEntry;
        });
        tmpEntries = tmpEntries.concat(this.entries);
        tmpEntries.sort((a, b) => {
          return a.time - b.time
        });
        tmpEntries.forEach(fun);
      }
      sort() {
        this.entries.sort((a, b) => {
          return b.time - a.time;
        });
      }
      cssClass() {
        if (this.page.total == this) return 'total';
        return '';
      }
      get isGroup() {
        return true
      }
      getVarianceForProperty(property) {
        var sum = 0;
        this.entries.forEach((entry) => {
          sum += entry[property + 'Variance'] * entry[property +
            'Variance'];
        });
        return Math.sqrt(sum);
      }
      get timeVariancePercent() {
        if (this._time == 0) return 0;
        return this.getVarianceForProperty('time')  / this._time * 100
      }
      get timeVariance() {
        return this.getVarianceForProperty('time')
      }
    }

    class UnclassifiedEntry extends GroupedEntry {
      constructor(page, color) {
        super('Unclassified', undefined, color);
        this.page = page;
        this._time = undefined;
        this._count = undefined;
      }
      add(entry) {
        this.entries.push(entry);
        entry.parent = this;
        return true;
      }
      forEachPageGroup(fun) {
        this.page.forEachGroup((group) => {
          if (group == this) return;
          if (group == this.page.total) return;
          fun(group);
        });
      }
      get time() {
        if (this._time === undefined) {
          this._time = this.page.total._time;
          this.forEachPageGroup((group) => {
            this._time -= group._time;
          });
        }
        return this.getCompareWithBaseline(this._time, '_time');
      }
      get count() {
        if (this._count === undefined) {
          this._count = this.page.total._count;
          this.forEachPageGroup((group) => {
            this._count -= group._count;
          });
        }
        return this.getCompareWithBaseline(this._count, '_count');
      }
    }
  </script>
</head>

<body id="body" onmousemove="handleUpdatePopover(event)" onload="handleBodyLoad()" class="noDiff">
  <h1>Runtime Stats Komparator</h1>

  <div id="results">
    <div class="inline">
      <h2>Data</h2>
      <form name="fileForm">
        <p>
          <input id="uploadInput" type="file" name="files" onchange="handleLoadFile();" accept=".json">
        </p>
      </form>
    </div>

    <div class="inline hidden">
      <h2>Result</h2>
      <div class="compareSelector inline">
        Compare against:&nbsp;<select id="baseline" onchange="handleSelectBaseline(this, event)"></select><br/>
        <span style="color: #060">Green</span> the selected version above performs
        better on this measurement.
      </div>
    </div>
    
    <div id="versionSelector" class="inline toggleContentVisibility">
      <h2>Version Selector</h2>
      <div class="content hidden">
        <ul></ul>
      </div>
    </div>
    
    <div id="pageSelector" class="inline toggleContentVisibility">
      <h2>Page Selector</h2>
      <div class="content hidden">
        <ul></ul>
      </div>
    </div>

    <div id="view">
    </div>

    <div id="detailView" class="hidden">
      <div class="versionDetail inline toggleContentVisibility">
        <h3><span></span></h3>
        <div class="content">
          <table class="versionDetailTable" onclick="handleSelectDetailRow(this, event);">
            <thead>
              <tr>
                <th class="version">Version&nbsp;</th>
                <th class="position">Pos.&nbsp;</th>
                <th class="value time">Time▴&nbsp;</th>
                <th class="value time">Percent&nbsp;</th>
                <th class="value count">Count&nbsp;</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
      </div>
      <div class="pageDetail inline toggleContentVisibility">
        <h3>Page Comparison for <span></span></h3>
        <div class="content">
          <table class="pageDetailTable" onclick="handleSelectDetailRow(this, event);">
            <thead>
              <tr>
                <th class="page">Page&nbsp;</th>
                <th class="value time">Time&nbsp;</th>
                <th class="value time">Percent▾&nbsp;</th>
                <th class="value time hideNoDiff">%/Entry&nbsp;</th>
                <th class="value count">Count&nbsp;</th>
              </tr>
            </thead>
            <tfoot>
              <tr>
                <td class="page">Total:</td>
                <td class="value time"></td>
                <td class="value time"></td>
                <td class="value time hideNoDiff"></td>
                <td class="value count"></td>
              </tr>
            </tfoot>
            <tbody></tbody>
          </table>
        </div>
      </div>
      <div class="impactView inline toggleContentVisibility">
        <h3>Impact list for <span></span></h3>
        <div class="content">
          <table class="pageDetailTable" onclick="handleSelectDetailRow(this, event);">
            <thead>
              <tr>
                <th class="page">Name&nbsp;</th>
                <th class="value time">Time&nbsp;</th>
                <th class="value time">Percent▾&nbsp;</th>
                <th class="">Top Pages</th>
              </tr>
            </thead>
            <tbody></tbody>
          </table>
        </div>
      </div>
    </div>
    <div id="pageVersionGraph" class="graph hidden toggleContentVisibility">
      <h3><span></span></h3>
      <div class="content"></div>
    </div>
    <div id="pageGraph" class="graph hidden toggleContentVisibility">
      <h3><span></span></h3>
      <div class="content"></div>
    </div>
    <div id="versionGraph" class="graph hidden toggleContentVisibility">
      <h3><span></span></h3>
      <div class="content"></div>
    </div>

    <div id="column" class="column">
      <div class="header">
        <select class="version" onchange="handleSelectVersion(this, event);"></select>
        <select class="pageVersion" onchange="handleSelectPage(this, event);"></select>
      </div>
      <table class="list" onclick="handleSelectRow(this, event);">
        <thead>
          <tr>
            <th class="position">Pos.&nbsp;</th>
            <th class="name">Name&nbsp;</th>
            <th class="value time">Time&nbsp;</th>
            <th class="value time">Percent&nbsp;</th>
            <th class="value count">Count&nbsp;</th>
          </tr>
        </thead>
        <tbody></tbody>
      </table>
    </div>
  </div>

  <div class="inline">
    <h2>Usage</h2>
    <ol>
      <li>Install scipy, e.g. <code>sudo aptitude install python-scipy</code>
      <li>Build chrome with the <a href="https://codereview.chromium.org/1923893002">extended runtime callstats</a>.</li>
      <li>Run <code>callstats.py</code> with a web-page-replay archive:
        <pre>$V8_DIR/tools/callstats.py run \
        --replay-bin=$CHROME_SRC/third_party/webpagereplay/replay.py \
        --replay-wpr=$INPUT_DIR/top25.wpr \
        --js-flags="" \
        --with-chrome=$CHROME_SRC/out/Release/chrome \
        --sites-file=$INPUT_DIR/top25.json</pre>
      </li>
      <li>Move results file to a subdirectory: <code>mkdir $VERSION_DIR; mv *.txt $VERSION_DIR</code></li>
      <li>Repeat from step 1 with a different configuration (e.g. <code>--js-flags="--nolazy"</code>).</li>
      <li>Create the final results file: <code>./callstats.py json $VERSION_DIR1 $VERSION_DIR2 > result.json</code></li>
      <li>Use <code>results.json</code> on this site.</code>
    </ol>
  </div>

  <div id="popover">
    <div class="popoverArrow"></div>
    <table>
      <tr>
        <td class="name" colspan="6"></td>
      </tr>
      <tr>
        <td>Page:</td>
        <td class="page name" colspan="6"></td>
      </tr>
      <tr>
        <td>Version:</td>
        <td class="version name" colspan="3"></td>
        <td class="compare version name" colspan="3"></td>
      </tr>
      <tr>
        <td>Time:</td>
        <td class="time"></td><td>±</td><td class="timeVariance"></td>
        <td class="compare time"></td><td class="compare"> ± </td><td class="compare timeVariance"></td>
      </tr>
      <tr>
        <td>Percent:</td>
        <td class="percent"></td><td>±</td><td class="percentVariance"></td>
        <td class="compare percent"></td><td class="compare"> ± </td><td class="compare percentVariance"></td>
      </tr>
      <tr>
        <td>Percent per Entry:</td>
        <td class="percentPerEntry"></td><td colspan=2></td>
        <td class="compare percentPerEntry"></td><td colspan=2></td>
      </tr>
      <tr>
        <td>Count:</td>
        <td class="count"></td><td>±</td><td class="countVariance"></td>
        <td class="compare count"></td><td class="compare"> ± </td><td class="compare countVariance"></td>
      </tr>
      <tr>
        <td>Overall Impact:</td>
        <td class="timeImpact"></td><td>±</td><td class="timePercentImpact"></td>
        <td class="compare timeImpact"></td><td class="compare"> ± </td><td class="compare timePercentImpact"></td>
      </tr>
    </table>
  </div>
</body>
</html>
